在 MVVM 方法中简化 ICommand/RelayCommand
Posted
技术标签:
【中文标题】在 MVVM 方法中简化 ICommand/RelayCommand【英文标题】:Simplifying ICommand/RelayCommand in a MVVM approach 【发布时间】:2012-04-13 06:47:15 【问题描述】:我正在推动自己使我编写的应用程序更简单,并且我已经采取了一些措施来做到这一点,但我遇到了一个有趣的问题,我觉得这并不是我独有的.我想知道我做错了什么。
我有一个保存模型对象集合的 ViewModel。该视图是一个 ListView,它显示集合中的所有对象。模型对象具有操作它们的所有逻辑。在每个项目的 ListView 行内,我都有一个按钮,并且需要连接该按钮才能调用模型对象上的方法。
要让它工作,我需要添加一个命令绑定,但要添加到父窗口数据上下文,它在行中传递模型对象的参数,以便模型对象可以在 ViewModel(父窗口数据上下文)来调用正在传入的模型对象上的方法。
这看起来确实比它需要的复杂得多。我愿意扔掉我已经做过的任何事情,没有神圣的奶牛,我只是希望以一种更简单的方法来完成,这样一年后回顾起来很容易弄清楚我在做什么。
【问题讨论】:
您可以将绑定与指定父窗口的 RelativeSource 一起使用,然后使用属性 DataContext.MyCommand。 为什么你的模型不创建一个由模型视图中的按钮直接调用的命令绑定? 我也想过这样做,但尽管我很乐意将业务逻辑嵌入到我的模型中,使用 System.Windows 中的部分 .NET 库(DependencyObject - 所以我可以绑定) 和 System.Windows.Input (ICommand/RoutedCommand) 在模型对象中似乎是错误的。 【参考方案1】:Binding RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type Window,
Path=DataContext.MyCommand
【讨论】:
如果我只是实现它,这正是我会做的事情,但我的问题不在于如何做到这一点,而是有一种更简单但不那么迟钝的方法。 您可以编写一个标记扩展来简化所述绑定的表达式。 我现在正在尝试,但理想情况下,我希望标记扩展能够直接访问该对象。类似于:Command=app:CustomExtension Object=CurrentObject, MethodName=MethodName
我正在努力让它发挥作用。
我最终创建了一个自定义 DelegateCommand 类(基于 Prism 类),该类继承自 DependencyObject 并将属性声明为依赖属性。然后我直接使用自定义转换器绑定到按钮上的 Command 属性。
@Andrew 嗨。你能提供一些关于你的 las 解决方案的示例吗?【参考方案2】:
在您的 ViewModel 中为模型对象创建一个演示者类并拥有这些对象的集合。然后,您可以将 ICommand 属性放在这些对象上,并将引用传递给您要在父数据上下文中调用的方法。
可能类似于以下内容:
public class ModelPresenter : INotifyPropertyChanged
private Model _model;
public ModelPresenter(Model model, Action<Model> parentAction)
_model = model
_action = parentAction;
public ICommand MyAction
get return new RelayCommand(() => _parentAction(_model));
...
听起来您可能正在绑定到您的模型的属性您的视图。您不应该这样做,因为如果您的模型没有实现 INotifyPropertyChanged,它可能会导致内存泄漏(请参阅:http://support.microsoft.com/kb/938416/en-us)。
【讨论】:
我直接绑定到模型,但我选择在我的所有模型元素上强制执行 INotifyPropertyChanged 以完成此操作。以上是关于在 MVVM 方法中简化 ICommand/RelayCommand的主要内容,如果未能解决你的问题,请参考以下文章