C# 如何引用viewmodel的页面(视图)?
我以前已经有人帮过我了,但是现在我正在把所有的东西都重写到MVVM中,我已经失去了这样做的能力。。。又来了 在MVVM重写之前,我在页面后面的代码中有一行代码:C# 如何引用viewmodel的页面(视图)?,c#,wpf,mvvm,mahapps.metro,C#,Wpf,Mvvm,Mahapps.metro,我以前已经有人帮过我了,但是现在我正在把所有的东西都重写到MVVM中,我已经失去了这样做的能力。。。又来了 在MVVM重写之前,我在页面后面的代码中有一行代码: var window = MahApps.Metro.Controls.TreeHelper.TryFindParent<MetroWindow>(this); var window=MahApps.Metro.Controls.TreeHelper.TryFindParent(此); 在结尾,“this”是指页面。现在
var window = MahApps.Metro.Controls.TreeHelper.TryFindParent<MetroWindow>(this);
var window=MahApps.Metro.Controls.TreeHelper.TryFindParent(此);
在结尾,“this”是指页面。现在,这段代码在我的viewmodel中有一条弯曲的红线,我不知道用什么来替换它。我想我不能说:
SideBar sb = new SideBar();
var window = MahApps.Metro.Controls.TreeHelper.TryFindParent<MetroWindow>(sb);
侧栏sb=新侧栏();
var window=MahApps.Metro.Controls.TreeHelper.tryfindpress(sb);
因为这将创建一个新的边栏实例。。。不是吗?顺便说一句,此页面作为主页内框架的默认源加载,而不是通过代码启动。您可以将窗口作为某些操作的参数传递给视图模型
<Button Content="Test"
Command="{Binding ShowPopupCommand}"
CommandParameter="{Binding RelativeSource=
{RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" />
继电器命令的代码
public class RelayCommand<T> : ICommand
where T : class
{
private Action<T> execute;
private Func<T, bool> canExecute;
public RelayCommand(Action<T> execute, Func<T, bool> canExecute = null)
{
this.execute = execute;
this.canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return this.canExecute == null || this.canExecute(parameter as T);
}
public void Execute(object parameter)
{
this.execute(parameter as T);
}
}
public class RelayCommand : RelayCommand<object>
{
public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
: base(execute, canExecute)
{
}
}
您没有将新的
侧栏
实例添加到可视化树中,因此当然没有MetroWindow
父对象,因为它根本没有父对象
我建议您更加熟悉MVVM模式。视图模型应该没有实际UI的概念。我已经基于MahApps.Metro和Autofac编写了一篇文章,也许这可以成为您的起点。永远不要尝试像这样1:1重写代码。。。您的viewmodel根本不应该调用这样的方法!重新思考您的方法,因为MVVM不是
从codebehind获取我的代码并将其放入一个单独的类中。。。但我对这一行的情况完全不熟悉真的。。。我想达到同样的效果。你知道我能做些什么吗?很明显,它试图找到对象的父对象,在这个例子中是一个页面的父对象,这就是窗口。。。不确定以后如何在代码中使用它,但您的ViewModel不应该知道有关窗口或页面的任何信息。如果需要的话,您需要将该逻辑放在别处……下一行代码是:wait DialogManager.ShowMessageAsync(窗口,“MESSAGE HERE”);据我所知,如果你不知道窗户的情况,你是不可能称之为这个的。。。。我不知道这段代码还能到哪里去?它应该通知其他类来显示消息,但它不应该直接负责处理这样的事情。据它所知,它只会触发显示消息,但这取决于其他人。ViewModel不应该关心它是WPF消息框,还是网站javascript弹出窗口,甚至是一些控制台输出。。这就是MVVM的意义所在——分离层和关注点,使代码可测试、可管理和可重用。尽可能避免紧耦合。如何准确地实现这一点是一个长期讨论的问题,没有明确的答案。你会如何像这样测试VM?我无法让参数通过。。。这是我的自动取款机,我应该把参数放在哪里?statsRefresh=newrelaycommand(param=>this.statsRefresh\u Click(),null);然后,我的方法:public void StatsRefresh_Click(MetroWindow窗口)感谢您的编辑-我仍然感到困惑,抱歉!我已经有了一个中继命令,但它有点不同-我可以将该中继命令也粘贴进去并使其过载吗?然后。。。通过运行ShowPopupCommand=new RelayCommand(…这会运行一个单独的方法吗?我当前的命令会将我想要运行的方法传递给relay命令…但我在你的命令中看不到这一点?抱歉!:(@BrunoLM:这个有效的MVVM模式在哪个世界?@Tseng说你想引用窗口来关闭它,如果不引用窗口,你怎么实现它?
public class RelayCommand<T> : ICommand
where T : class
{
private Action<T> execute;
private Func<T, bool> canExecute;
public RelayCommand(Action<T> execute, Func<T, bool> canExecute = null)
{
this.execute = execute;
this.canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return this.canExecute == null || this.canExecute(parameter as T);
}
public void Execute(object parameter)
{
this.execute(parameter as T);
}
}
public class RelayCommand : RelayCommand<object>
{
public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
: base(execute, canExecute)
{
}
}
public class MainViewModel
{
public MainViewModel()
{
ShowPopupCommand = new RelayCommand(o =>
{
var wnd = o as Window;
var putBreakPointhere = 1;
});
}
public ICommand ShowPopupCommand { get; set; }
}