我有一个View,它有2个子视图,ViewModel分配给每个视图:
ViewParent - ViewModelParent
{
ViewA - ViewModelA
ViewB - ViewModelB
}
ViewParent
结构如下所示。
<StackPanel Orientation="Vertical">
<local:AView DataContext="{Binding ViewModelA, Mode=TwoWay}"></localViews:AView>
</StackPanel>
<StackPanel Orientation="Vertical">
<localViews:BView DataContext="{Binding ViewModelB, Mode=TwoWay}"></localViews:BView>
</StackPanel>
现在在ViewA
后面的代码中,我有一个事件要在gridview中选择一行。
private void radGridView_SelectionChanged(object sender, SelectionChangeEventArgs e)
{
try
{
RadGridView grv = sender as RadGridView;
if (e.AddedItems.Count > 0)
{
var row = grv.SelectedItem as SomeClass;
if(condition)
// Enable a button in ViewB.
我想要的是将row
传递给ViewModelB
。另外,我想在ViewB中启用一个按钮。最后,我想将ViewModelA
中的几个整数传递给ViewModelB
。
怎么做?我考虑过构造函数注入,但仍然没有明确的想法。
答案 0 :(得分:1)
这里有很多打字,但没有困难的逻辑,没有任何东西可以变成一个错误并咬你。
确保ParentViewModel
引用ViewModelA
和ViewModelB
(据我所知,您已经在那里)。
给ViewModelA
SelectedRowChanged
个事件:
public event EventHandler SelectedRowChanged;
为ViewModelB
提供IsMyButtonEnabled
属性(但请将其命名为更好;您需要使用名称来指示指的是哪个按钮)
private bool _isMyButtonEnabled;
public bool IsMyButtonEnabled {
get { return _isMyButtonEnabled; }
set {
_isMyButtonEnabled = value;
OnPropertyChanged(nameof(IsMyButtonEnabled));
}
}
在ViewB
中,将按钮的IsEnabled
属性绑定到该属性:
<Button
...
IsEnabled="{Binding IsMyButtonEnabled}"
...
同时为ViewModelA
和ViewModelB
提供SelectedRow
属性。
private SomeClass _selectedRow;
public SomeClass SelectedRow {
get { return _selectedRow; }
set {
_selectedRow = value;
OnPropertyChanged(nameof(SelectedRow));
/*
DO ADDITIONAL STUFF HERE:
VMA:
SelectedRowChanged?.Invoke(this, EventArgs.Empty);
VMB:
Set IsMyButtonEnabled to whatever is appropriate based on
the selected row.
*/
}
}
ParentViewModel
为ViewModelA.SelectedRowChanged
设置了一个处理程序,它可以执行此操作,因为它具有对其ViewModelA
实例的引用。然后处理程序告诉ViewModelB
做一些在SelectedRow更改时需要完成的事情。另一种方法是为ViewModelB
提供ViewModelA
的引用,并让它处理ViewModelA.SelectedRowChanged
。但作为一项规则,您希望您的子视图模型比这更松散耦合。你不希望B 依赖有一个类型A的兄弟。但是父已经取决于拥有这两个孩子。一分钱,一磅。你不能再弄湿了。
...
// Constructor or someplace
this.VMA = new ViewModelA();
this.VMA.SelectedRowChanged += ViewModelA_SelectedRowChanged;
...
void ViewModelA_SelectedRowChanged(Object sender, EventArgs e)
{
// VMB.SelectedItem's setter will enable the button appropriately
VMB.SelectedItem = VMA.SelectedItem;
}
你真的应该&#34;应该&#34;使用Command执行按钮操作,并启用Command而不是具有Is*ButtonEnabled
属性。这是一种更通用,更强大的做事方式。但我们可以一步一步走。