UserControl中的INotifyPropertyChanged

use*_*541 11 c# silverlight-4.0

我有一个继承自TextBox控件的自定义控件.我想INotifyPropertyChanged在我的自定义控件中实现该接口.

public class CustomTextBox : TextBox, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(info));
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是当我尝试引发PropertyChanged事件时,PropertyChanged事件处理程序始终为null.

有人可以帮帮我吗?

Ree*_*sey 13

PropertyChanged事件处理程序为null.

在订阅PropertyChanged事件之前,这将始终为真.

通常,如果您正在制作自定义控件,则不会使用INotifyPropertyChanged.在这种情况下,您将改为创建自定义依赖项属性.通常,依赖项对象(即:控件)都将使用依赖项属性,而INPC将由成为DataContext这些对象的类使用.这允许绑定系统正常工作.


Ton*_*ina 7

你有什么期望?PropertyChanged事件由UI代码使用,但在您写作的意义上并非如此.控件从不实现INPC(INotifyPropertyChanged的简称),它们绑定到已实现 INPC的对象.这样,某些UI属性(例如TextBox控件上的Text属性)绑定到此类上的属性.这是MVVM架构的基础.

例如,您将编写以下XAML代码:

<TextBlock x:Name="txtBox" Text="{Binding Title}" />
Run Code Online (Sandbox Code Playgroud)

然后以下列方式在代码中设置TextBlock(或其任何祖先,传播DataContext)的数据上下文:

txtBox.DataContext = new Movie {Title = "Titanic"};
Run Code Online (Sandbox Code Playgroud)

现在为班级本身:

public class Movie : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(info));
    }

    private string _title;
    public string Title
    {
        get { return _title; }
        set
        {
            if (_title == value) return;

            _title = value;
            NotifyPropertyChanged("Title");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,无论何时更改Title属性,无论是在代码中还是通过其他绑定,UI都将自动刷新.Google for Data Binding和MVVM.

  • 这是在数据发生变化时更新控件,但我认为OP正在尝试实现双向绑定,其中UserControl会自动更新数据源.据推测,有一些方法可以通知用户控件已更新属性,但我还没有找到. (3认同)

Dev*_*per 5

像我在评论中说的那样做。它不像你那样工作。只需创建一个额外的类,并实现Notification Interface那里,这个类应用到DataContextUserControl。它会像你需要的那样工作。

 public partial class W3 : UserControl
    {
        WeatherViewModel model = new WeatherViewModel();

        public W3()
        {
            InitializeComponent();
            this.DataContext = model;
        }

        public void UpdateUI(List<WeatherDetails> data, bool isNextDays)
        {
            model.UpdateUI(data, isNextDays);
        }
    }

    class WeatherViewModel : INotifyPropertyChanged
    {     

        public void UpdateUI(List<WeatherDetails> data, bool isNextDays)
        {
            List<WeatherDetails> weatherInfo = data;
            if (weatherInfo.Count != 0)
            {
                CurrentWeather = weatherInfo.First();
                if (isNextDays)
                    Forecast = weatherInfo.Skip(1).ToList();
            }
        }

        private List<WeatherDetails> _forecast = new List<WeatherDetails>();

        public List<WeatherDetails> Forecast
        {
            get { return _forecast; }
            set
            {
                _forecast = value;
                OnPropertyChanged("Forecast");
            }
        }

        private WeatherDetails _currentWeather = new WeatherDetails();

        public WeatherDetails CurrentWeather
        {
            get { return _currentWeather; }
            set
            {
                _currentWeather = value;
                OnPropertyChanged("CurrentWeather");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
Run Code Online (Sandbox Code Playgroud)