BaseClass C#上的INotifyPropertyChanged和属性#

时间:2016-07-07 16:50:21

标签: c# wpf xaml mvvm

我正在使用WPF和MVVM模型。我有一个名为ViewModelBase的基本viewmodel类。它有一个名为Config的属性,它是一种复杂类型。我需要一个派生类,以便能够在视图中数据绑定到基类Config属性。

public class ViewModelBase : INotifyPropertyChanged
{
    private Configuration _config;
    public event PropertyChangedEventHandler PropertyChanged;

    public Configuration Config
    {
        get { return _config; }
        set
        {
            if(_config == null || !_config.Equals(value))
            {
                _config = value;
                OnPropertyChanged(new PropertyChangedEventArgs("Config"));
            }
        }
    }

    public ViewModelBase()
    {
    }

    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if(PropertyChanged != null)
        {
            PropertyChanged(this, e);
        }
    }
}

数据绑定似乎在读取容量中工作,但是当在OptionsView中更改Config的属性时,更改不会反映在Config本身中。有什么建议吗?

按要求配置实施。

    public class Configuration : IEquatable<Configuration>, INotifyPropertyChanged
{
    private string _primaryUrl;
    private string _secondaryUrl;
    private DateTime _scheduledStart;
    private DateTime _scheduledEnd;
    private string _buffer;
    private bool _isScheduleEnabled;
    private int _logDays;
    private int _retryDuration;
    private int _maxRetryAttempts;
    private string _registrationKey;
    private string _email;

    public string PrimaryURL
    {
        get { return _primaryUrl; }
        set
        {
            if(_primaryUrl != value)
            {
                _primaryUrl = value;
                OnPropertyChanged(new PropertyChangedEventArgs("PrimaryURL"));
            }
        }
    }
    public string SecondaryURL
    {
        get { return _secondaryUrl; }
        set
        {
            if(_secondaryUrl != value)
            {
                _secondaryUrl = value;
                OnPropertyChanged(new PropertyChangedEventArgs("SecondaryURL"));
            }
        }
    }
    public DateTime ScheduledStart
    {
        get { return _scheduledStart; }
        set
        {
            if(_scheduledStart != value)
            {
                _scheduledStart = value;
                OnPropertyChanged(new PropertyChangedEventArgs("ScheduledStart"));
            }
        }
    }
    public DateTime ScheduledEnd
    {
        get { return _scheduledEnd; }
        set
        {
            if(_scheduledEnd != value)
            {
                _scheduledEnd = value;
                OnPropertyChanged(new PropertyChangedEventArgs("ScheduledEnd"));
            }
        }
    }
    public string Buffer
    {
        get { return _buffer; }
        set
        {
            if(_buffer != value)
            {
                _buffer = value;
                OnPropertyChanged(new PropertyChangedEventArgs("Buffer"));
            }
        }
    }
    public bool IsScheduleEnabled
    {
        get { return _isScheduleEnabled; }
        set
        {
            if(_isScheduleEnabled != value)
            {
                _isScheduleEnabled = value;
                OnPropertyChanged(new PropertyChangedEventArgs("IsScheduleEnabled"));
            }
        }
    }
    public int LogDays
    {
        get { return _logDays; }
        set
        {
            if(_logDays != value)
            {
                _logDays = value;
                OnPropertyChanged(new PropertyChangedEventArgs("LogDays"));
            }
        }
    }
    public int RetryDuration
    {
        get { return _retryDuration; }
        set
        {
            if(_retryDuration != value)
            {
                _retryDuration = value;
                OnPropertyChanged(new PropertyChangedEventArgs("RetryDuration"));
            }
        }
    }
    public int MaxRetryAttempts
    {
        get { return _maxRetryAttempts; }
        set
        {
            if(_maxRetryAttempts != value)
            {
                _maxRetryAttempts = value;
                OnPropertyChanged(new PropertyChangedEventArgs("MaxRetryAttempts"));
            }
        }
    }
    public string RegistrationKey
    {
        get { return _registrationKey; }
        set
        {
            if(_registrationKey != value)
            {
                _registrationKey = value;
                OnPropertyChanged(new PropertyChangedEventArgs("RegistrationKey"));
            }
        }
    }
    public string Email
    {
        get { return _email; }
        set
        {
            if(_email != value)
            {
                _email = value;
                OnPropertyChanged(new PropertyChangedEventArgs("Email"));
            }
        }
    }

    public Configuration() { }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if(PropertyChanged != null)
        {
            PropertyChanged(this, e);
        }
    }
}

这是罪魁祸首之一:

<xctk:DateTimePicker Grid.Column="1" Value="{Binding Config.ScheduledStart}" Height="20" VerticalAlignment="Top"/>

2 个答案:

答案 0 :(得分:1)

  

数据绑定似乎在读取容量中工作..

哪个没问题,但如果您想要更改容量,那么课程Configuration必须遵守INotifyPropertyChanged,并且课程中的每个属性都需要报告PropertyChange通知以进行任何更改在绑定的xaml控件中显示。

  

但是当在OptionsView中更改Config的属性时,不会反映更改

您现在只有在Configuration实例被替换后才会通知您;不是单个属性更改当前实例中。

答案 1 :(得分:1)

INotifyPropertyChanged实现仅适用于该类。所以在你的情况下,ViewModelBase类及其子类型。

在这种情况下,PropertyChangedEventConfig属性的setter中引发,因此每当设置Config属性(并调用setter)时,都会引发事件

然而,这并不意味着当突变 Config对象时,偶数也会被提升。一般来说,情况并非如此。

为了在更改Config对象时引发事件,您必须将对象重新分配给视图模型(再次调用setter)。但是,当数据绑定到对象时,这不起作用。

更好的解决方案是在Configuration实现INotifyPropertyChanged接口本身。因此,当该对象中的属性发生更改时,也会引发一个事件。 WPF也会识别这个子对象,因此它会自动运行。