从一个“视图”传递财产到 MVVM 中其他视图的视图模型
我是 MVVM 新手,有一些小问题。我有两个用户控件:父控件和子控件(带有视图、视图模型、模型类)。并且需要将一些属性从父级传递给子级。现在我通过编写这样的代码来管理它:
public static readonly DependencyProperty CallbackActionProperty =
DependencyProperty.Register("CallbackAction", typeof (Action),
typeof (ChildView), new PropertyMetadata(default(Action)));
public Action CallbackAction
{
get { return (Action) GetValue(CallbackActionProperty); }
set
{
SetValue(CallbackActionProperty, value);
((ChildViewModel)this.DataContext).CallbackAction = value; // Change ViewModel property too
}
}
这是 ChildView
中的依赖属性,并且在其集合上我还设置了其 ViewModel
的属性。之后,我从 ParentView
访问该依赖项属性并设置 CallbackAction
->在 Child 的 ViewModel 中设置 CallbackAction
。
代码:
this.Loaded += (sender, args) => childUc.CallbackAction = ((ParentViewModel) this.DataContext).RefreshStatuses;
childUc
是用户控件,位于父级上,由ChildView
表示。 代码很丑陋,所以我希望在不破坏模式方面看到更好的实践。 谢谢。
Im new to MVVM and have small problem. I have two user controls: parent and child(with view, viewmodel, model classes). And need to pass some properties from parent to child. For now ive managed it by writing such code:
public static readonly DependencyProperty CallbackActionProperty =
DependencyProperty.Register("CallbackAction", typeof (Action),
typeof (ChildView), new PropertyMetadata(default(Action)));
public Action CallbackAction
{
get { return (Action) GetValue(CallbackActionProperty); }
set
{
SetValue(CallbackActionProperty, value);
((ChildViewModel)this.DataContext).CallbackAction = value; // Change ViewModel property too
}
}
This is dependency property in ChildView
and on its set i also set its ViewModel
's property. After that i access that dependency property from ParentView
and set the CallbackAction
-> that sets the CallbackAction
in Child's ViewModel.
Code:
this.Loaded += (sender, args) => childUc.CallbackAction = ((ParentViewModel) this.DataContext).RefreshStatuses;
childUc
is usercontrol, located on parent and represented by ChildView
.
Code is ugly, so i hope to see better practice in terms of not breaking pattern.
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的 - 这段代码非常难看。事实上,我正在努力弄清楚它到底是做什么的!
MVVM 模式的主要租户之一是 ViewModel 应该是可单元测试的,并且应该可以在没有视图的情况下执行它。面对这种问题时,只考虑视图Model而忽略视图。
您的 ParentViewModel 具有对 ChildViewModel 的引用,您可以通过在创建 ChildViewModel 时让 ParentViewModel 提供对其自身的引用来使其成为双向关系。这意味着您可以从 ChildViewModel 执行 ParentViewModel 上的任何公共方法。
考虑到这一点,您应该能够解决您的问题!
(此外,您不应在依赖属性 getter 或 setter 中添加逻辑,此代码可能会也可能不会被调用,具体取决于您的依赖属性值的设置方式。)
Yep - this code is pretty ugly. In fact I am struggling to work out exactly what it does!
One of the main tenants of the MVVM pattern is that the ViewModel should be unit testable and it should be possible to execute it without the view. When faced with this kind of problem, think about the view Model alone and ignore the view.
Your ParentViewModel has a reference to the ChildViewModel, you can make this a two way relationship by having the ParentViewModel provide a reference to itself when you create the ChildViewModel. This means that from the ChildViewModel you can execute any public method on the ParentViewModel.
With this in mind, you should be able to solve your problem!
(Also, you should not add logic in your dependency property getter or setter, this code may or may not be called depending on how your dependency property value is set.)
不要在 DependencyProperty 的 setter 或 getter 中编写任何逻辑,因为它由框架以其他方式调用,而不是直接通过 set/get 访问器调用。这是必须的规则。
另外,字符串
在当前 View 和底层 ViewModel 类型之间引入了绑定耦合,这不是 MVVM 原则。
如果存在视图依赖关系,您应该考虑使用 XAML 中的绑定来传递属性,否则 ParentViewModel 应该通过构造函数注入 ChildViewModel。所以它们应该被设计为表明 ParentViewModel 有一个 Child…
Do not write any logic in setter or getter of
DependencyProperty
because it called by the Framework in orher ways, not directly through the set/get accessors. This is a must rule.Also string
introduced tied coupling between current View and underlying ViewModel type, this is not a MVVM principle.
In case of View dependency you should consider passing of properties using bindings in XAML, otherwise ParentViewModel should has injected a ChildViewModel through constructor. So they should be designed to indicate that ParentViewModel has a Child one...