如何使用ViewModel-first从代码后台设置ViewModel属性?

5
在我的WPF(4.0)应用程序中,我使用Viewmodel-first模式。因此,我的viewmodel首先被创建,然后是视图 - 使用数据模板。一个工作演示可以在这里找到here
现在,在创建的视图(代码后台)中,我需要修改viewmodel的属性。在View-first方法中,我只需访问命名的viewmodel实例即可。但是,Viewmodel-first方法不允许此操作。有一个viewmodel,但是视图不关心它是什么。

BAD:

当然,您可以获取DataContext并使用它,但这实际上将view和viewmodel耦合在一起。
private void MyView_Loaded(object sender, RoutedEventArgs e)
{
    this.viewModel = DataContext as MyViewModel;
}

我需要一个推荐的模式来完成这个任务。命令?消息?请帮忙!

问:如何修改(设置属性)活动视图模型?


“我需要修改视图模型的属性。” => 很可能这个假设是错误的,有一种在架构上更可取的方式来实现所需的效果。那么具体是什么效果呢? - Jon
2个回答

4

使用绑定将数据从视图传递到ViewModel并激活ViewModel命令。

命令应使用绑定来执行ViewModel上的命令。

消息应用于ViewModel之间的通信。

.


这很棘手。我有一些高级的鼠标事件处理程序,依赖于视图模型中的数据。如果我无法访问它,如何成功实现鼠标/拖动逻辑呢? - l33t
是的。只需记住,在MVVM中,View显示ViewModel。它应该是被动的,ViewModel应该执行操作/命令。在View中,您应该只有处理UI事件以进行显示目的的代码。 - Emond
实际上,我不同意从视图中访问ViewModel会破坏MVVM的说法。MVVM的真正目的是重用ViewModel和Model库。无论如何,视图都知道ViewModel的存在。如果视图主动违背ViewModel,才会破坏原本的结构。 - EngineerSpock
1
在我的情况下,有一个没有滚动能力的VirtualizingWrapPanel。不知何故,由用户点击(在“NextPage”按钮上)触发,我必须调用VirtualizingWrapPanel上的PageDown,以允许它呈现下一部分数据。VM无法计算可以同时呈现多少项。因此,我决定公开一个事件,需要View进行订阅。 - EngineerSpock
@engineerspock - 你是正确的。谢谢,我修改了我的答案。 - Emond
显示剩余4条评论

3

你不能这样做。否则,View将会了解到View Model。

如果此初始化在所有视图模型中都是通用的,则可以在ViewModelBase中定义属性/事件,并从该类派生所有视图模型。

问:如何修改(设置属性)活动视图模型?

您需要使用EventAggregator模式进行视图-视图模型通信。

您可以使用您喜欢的MVVM框架,几乎所有框架都支持EventAggregator(或MessageBusEnterprise Bus)。


能否使用EventAggregator模式(从视图内部)查询视图模型中的数据?我有几种情况需要在代码后台中进行视图模型查询 :( - l33t

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接