我仍然不确定我的方法是否正确,但在尝试实现MVVM模式时,我已按以下方式创建了一个模型类'Test':
public class Test : BindableBase
{
private int testNumber;
public int TestNumber
{
get { return testNumber; }
set { SetProperty(ref testNumber, value) }
}
...
}
然后我在ViewModel
:
class ViewModel : BindableBase
{
private Test testVM;
public Test TestVM
{
get { return testVM; }
set { SetProperty(ref testVM, value); }
}
...
在View
的XAML代码中,我通过Test
属性绑定了TestVM
类的所有属性。虽然这很好用,但在尝试实现DelegateCommad
时遇到了问题。
public DelegateCommand StartTestCommand { get; private set; }
到目前为止,在实现DelegateCommand
时,如果我想在属性发生变化时触发CanExecute
方法,我会在属性的setter中包含DelegateCommand.RaiseCanExecuteChanged()
。像这样:
...
private bool duringTest;
public bool DuringTest
{
get { return duringTest; }
set
{
SetProperty(ref duringTest, value);
StartTestCommand.RaiseCanExecuteChanged();
}
}
...
这适用于ViewModel
中声明的属性,但是当对Test
属性使用相同的方法时,这不再有效。
...
private Test testVM;
public Test TestVM
{
get { return testVM; }
set
{
SetProperty(ref testVM, value);
StartTestCommand.RaiseCanExecuteChanged();
}
}
}
我希望每次更改TestVM
的属性时,都会调用setter,而是直接更新模型。
我做错了什么?在Model
中使用ViewModel
对象时的正确方法是什么?
答案 0 :(得分:1)
更改对象的属性值不会更改对象的引用。
声明此
public Test TestVM
{
get { return testVM; }
set
{
SetProperty(ref testVM, value);
StartTestCommand.RaiseCanExecuteChanged();
}
}
你基本上是在告诉编译器:当TestVM
对象的引用被改变时(甚至改为相同的值),更新StartTestCommand
的状态。
但很明显,一旦分配了该对象,就不会更改对该对象的引用。
如果要在某些子视图模型(ViewModel
)属性发生更改时更新父视图模型(Test
)中的命令,则可以使用PropertyChanged
事件:
public Test TestVM
{
get { return testVM; }
set
{
Test oldValue = testVM;
if (SetProperty(ref testVM, value))
{
if (oldValue != null)
{
oldValue.PropertyChanged -= TestPropertyChanged;
}
if (testVM!= null)
{
testVM.PropertyChanged += TestPropertyChanged;
}
}
}
}
void TestPropertyChanged(object sender, PropertyChangedEventArgs e)
{
// filter if necessary
if (e.PropertyName == "...")
{
StartTestCommand.RaiseCanExecuteChanged();
}
}