0

我仍然不确定我的方法是否正确,但为了尝试实现 MVVM 模式,我通过以下方式创建了一个模型类“测试”:

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; }

到目前为止,在实现DelegateCommands 时,如果我想CanExecute在属性发生更改时触发该方法,我将包含DelegateCommand.RaiseCanExecuteChanged()在属性的 setter 中。像这样:

    ...
    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什么?

4

1 回答 1

1

更改对象的属性值不会更改对象的引用。

声明这个

public Test TestVM
{
    get { return testVM; }
    set
    {
        SetProperty(ref testVM, value);
        StartTestCommand.RaiseCanExecuteChanged();
    }
}

您基本上是在告诉编译器:当对TestVM对象的引用发生更改(甚至更改为相同的值)时,更新StartTestCommand's 状态。

但是很明显,一旦分配了对该对象的引用,您就不会更改它。

如果您想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();
    }
}
于 2018-04-26T08:29:57.313 回答