MVVM:模型如何使用inotifypropertychanged来通知viewmodel更改

时间:2014-03-10 21:12:42

标签: c# wpf mvvm inotifypropertychanged

我需要Model来通知ViewModel是否有任何属性被更改,因为我需要收集集合中已更改的模型实例以进行进一步处理,还需要在viewmodel中启用和禁用命令按钮。 所以我使用了ModelBase抽象类并添加了HasChanges属性,我可以在viewmodel中测试它并捕获更改的模型。但它不起作用,我不知道我错过了什么。

public abstract class ModelBase : INotifyPropertyChanged
{
    protected ModelBase()
    {
    }

    private bool _hasChanges;
    public bool HasChanges
    {
        get
        { 
            return _hasChanges;
        }

        set
        {
            if (_hasChanges != value)
            {
                _hasChanges = value;
                RaisePropertyChanged("HasChanges");
            }
        }
    }

    protected void RaisePropertyChanged(string propertyName)
    {
        HasChanges = true;
        this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        var handler = this.PropertyChanged;

        if (handler != null)
        {
            handler(this, e);
        }
    }
}

Model被包装在ViewModel中并绑定到View DataGrid

private Model_selectedModel;

public Mode SelectedModel
{
    get 
    {
        return _selectedModel; 
    }

    set
    {
        if (_selectedModel != value)
        {
            _selectedModel = value;
            NotifyPropertyChanged("SelectedModel");
        }
    }
}

感谢您提供宝贵的帮助。

1 个答案:

答案 0 :(得分:0)

我测试了你的课,没关系。我认为这一点是错字:

private Model_selectedModel;

public Mode SelectedModel
{
    get 
    {
        return _selectedModel; 
    }

    set
    {
        if (_selectedModel != value)
        {
            _selectedModel = value;
            NotifyPropertyChanged("SelectedModel");
        }
    }
}

应该有 RaisePropertyChanged 而不是 NotifyPropertyChanged

下面是我的测试:

XAML

<Window x:Class="TestUpdatePropertyChanged.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:this="clr-namespace:TestUpdatePropertyChanged"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <this:TestViewModel />
    </Window.DataContext>

    <Grid>
        <TextBox Width="100" Height="25" Text="{Binding Path=TestString, UpdateSourceTrigger=PropertyChanged}" />

        <Button Width="100" Height="30" VerticalAlignment="Top" Content="Click" Click="Button_Click" />
    </Grid>
</Window>

Code-behind

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var testData = this.DataContext as TestViewModel;

        testData.TestString = "Yay, it's change!";

        if (testData.HasChanges == true) 
        {
            MessageBox.Show("It's Change!");
        }
    }
}

public class TestViewModel : ModelBase 
{
   private string _testString = "test";

    public string TestString
    {
        get { return _testString; }

        set
        {
            if (_testString != value)
            {
                _testString = value;
                RaisePropertyChanged("TestString");
            }
        }
    }
} 

public abstract class ModelBase : INotifyPropertyChanged
{
    protected ModelBase()
    {
    }

    private bool _hasChanges;
    public bool HasChanges
    {
        get
        { 
            return _hasChanges;
        }

        set
        {
            if (_hasChanges != value)
            {
                _hasChanges = value;
                RaisePropertyChanged("HasChanges");
            }
        }
    }

    protected void RaisePropertyChanged(string propertyName)
    {
        HasChanges = true;
        this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        var handler = this.PropertyChanged;

        if (handler != null)
        {
            handler(this, e);
        }
    }
}