14

TextBox コントロールから継承されたカスタム コントロールがあります。INotifyPropertyChangedカスタム コントロールにインターフェイスを実装したいと思います。

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

私の問題は、PropertyChanged イベントを発生させようとすると、PropertyChanged イベント ハンドラーが常に null になることです。

誰でも私を助けることができますか?

4

3 に答える 3

15

PropertyChanged イベント ハンドラーは常に null です。

これは、何かがイベントをサブスクライブするまで常に true になりますPropertyChanged

ただし、通常、カスタム コントロールを作成する場合は、INotifyPropertyChanged. このシナリオでは、代わりにカスタム依存関係プロパティを作成します。通常、依存オブジェクト (つまり、コントロール) はすべて依存関係プロパティを使用し、INPC はDataContextこれらのオブジェクトになるクラスによって使用されます。これにより、バインディング システムが適切に機能します。

于 2012-09-17T19:56:15.230 に答える
10

PropertyChanged イベントは UI コードで使用されますが、作成しているという意味ではありません。コントロールは INPC (INotifyPropertyChanged の略) を実装することはなく、 INPCを実装したオブジェクトにバインドされます。このように、特定の UI プロパティ ( TextBox コントロールのTextプロパティなど) は、そのようなクラスのプロパティにバインドされます。これが MVVM アーキテクチャの基礎です。

たとえば、次の XAML コードを記述します。

<TextBlock x:Name="txtBox" Text="{Binding Title}" />

そして、TextBlock (またはその祖先のいずれか、DataContext が伝達される) のデータ コンテキストを次の方法でコードに設定します。

txtBox.DataContext = new Movie {Title = "Titanic"};

そして今、クラス自体のために:

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

Title propertyこれで、コードまたは他のバインディングを介してを変更するたびに、UI が自動的に更新されます。データ バインディングMVVMの詳細については、こちらをご覧ください。

于 2012-09-17T20:03:13.750 に答える
5

私がコメントで言ったようにそれをしてください。あなたのようには機能しません。追加のクラスを作成してNotification Interfaceそこに実装し、このクラスを の に適用するDataContextだけUserControlです。そして、必要に応じて機能します。

 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));
        }
    }
于 2016-08-12T02:03:30.300 に答える