Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何引用viewmodel的页面(视图)?_C#_Wpf_Mvvm_Mahapps.metro - Fatal编程技术网

C# 如何引用viewmodel的页面(视图)?

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”是指页面。现在

我以前已经有人帮过我了,但是现在我正在把所有的东西都重写到MVVM中,我已经失去了这样做的能力。。。又来了

在MVVM重写之前,我在页面后面的代码中有一行代码:

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; }
}