在 WPF MVVM Light 中多次绑定到 RelayCommand

Posted

技术标签:

【中文标题】在 WPF MVVM Light 中多次绑定到 RelayCommand【英文标题】:Multiple binding to RelayCommand in WPF MVVM Light 【发布时间】:2019-05-16 08:31:53 【问题描述】:

我已经开始使用 WPF MVVM Light,现在我正在尝试在页面之间导航。

在主窗口中我添加了一个“BackButton”

<Button Command='Binding Main.GoBack, Mode=OneWay' />

绑定到 MainViewModel 方法“RelayCommand GoBack”。

private RelayCommand _goBack;
    public RelayCommand GoBack
    
        get
        
            return _goBack
                ?? (_goBack = new RelayCommand(
                () =>
                    _navigationService.GoBack();
                ));
        
    

为什么这个按钮只改变一次视图?如果我想第二次点击它 它不起作用(什么也没发生)。如果我通过另一个按钮将页面更改为另一个页面,则它只会一次又一次地开始工作。

FrameNavigationService的部分实现:

public FrameNavigationService()
    
        _pagesByKey = new Dictionary<string, Uri>();
        _historic = new List<string>();
    
    public void GoBack()
    
        if (_historic.Count > 1)
        
            _historic.RemoveAt(_historic.Count - 1);
            NavigateTo(_historic.Last(), null);
        
    
    public void NavigateTo(string pageKey)
    
        NavigateTo(pageKey, null);
    

    public virtual void NavigateTo(string pageKey, object parameter)
    
        lock (_pagesByKey)
        
            if (!_pagesByKey.ContainsKey(pageKey))
            
                throw new ArgumentException(string.Format("No such page: 0 ", pageKey), "pageKey");
            

            var frame = GetDescendantFromName(Application.Current.MainWindow, "MainFrame") as Frame;

            if (frame != null)
            
                frame.Source = _pagesByKey[pageKey];
            
            Parameter = parameter;
            _historic.Add(pageKey);
            CurrentPageKey = pageKey;
        
    

我能做些什么来处理这个问题?可能我应该做完全不同的事情吗?

【问题讨论】:

【参考方案1】:

你可能根本不应该做回退。

除非您真的想使用日记,否则使用框架和页面是个坏主意。返回桌面应用程序中的最后一个视图是一种罕见的要求。他们不是网络浏览器怎么办。

也许你有这个要求。

如果你有一个框架,那么你就有它的日志,你可以在框架的导航服务上调用 goback。 https://docs.microsoft.com/en-us/dotnet/api/system.windows.navigation.navigationservice.goback?view=netframework-4.8

您在页面上设置了 keepalive。 https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.page.keepalive?view=netframework-4.8

您编写了该代码,它似乎在很大程度上复制了导航服务功能。根据您向我们展示的内容。

原来如此。

使用类型而不是魔术字符串作为键。在编译时检查类型,而不是魔术字符串,您可能会出错。

您是否探讨过这个问题?我认为也许这是告诉某人他们做错了什么并没有告诉他们应该如何诊断那样真正有帮助的时候之一。

调试是任何开发人员的关键技能。

代码在你面前运行。

设置断点,逐步检查并检查正在发生的事情。

当您导航时,_historic 中的结果是什么?

当你返回时,究竟会发生什么?

当您第二次单击返回时,它会走哪条路径以及导致该路径的状态。

【讨论】:

也许我应该改变显示视图的方式?你能给我一个线索吗?现在,我有一个框架来加载我的页面。也许我不应该使用页面但其他的东西?而且不要在框架内做? 框架和页面最适合“向导”类型的过程,您可以在这些过程中在一系列视图中进行选择/填充数据,并且可能希望返回到先前的视图。我曾经工作过的所有团队都使用带有用户控件的内容控件。而不是框架和页面。常见的模式首先称为视图模型。如果你谷歌,你将能够找到例子。更多关于为什么框架不好的信息:social.technet.microsoft.com/wiki/contents/articles/… 一种简单的方法是使用选项卡控件并隐藏选项卡标题。它为您提供每个选项卡的索引,您只需递增/递减即可向前和向后移动。【参考方案2】:

确保您在 GalaSoft.MvvmLight.CommandWpf 中使用 RelayCommand,而不是在 GalaSoft.MvvmLight.Command.RelayCommand

【讨论】:

以上是关于在 WPF MVVM Light 中多次绑定到 RelayCommand的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 MVVM Light Toolkit 打开一个新窗口

C# mvvmlight model数据非自己定义可以绑定吗

如何使用 MVVM Light for WPF 在窗口中导航?

MVVM Light 绑定到 Observable 集合

如何在 WPF / MVVM 中对绑定到相同实例的两个列表视图进行不同选择

WPF:如何使用 MVVM 将命令绑定到 ListBoxItem?