Связывание WPF с INotifyPropertyChanged не обновляется - PullRequest
7 голосов
/ 19 июня 2010

У меня возникают серьезные проблемы с обновлением пользовательского интерфейса WPF при обновлении при обновлении свойства, с которым оно связано.Вот мое определение класса модели представления:

namespace WpfModel
    {
        class AppModel : INotifyPropertyChanged
        {
            private int _count = 7;

        public int Count { get { return _count; } 
        set { _count = value;     OnPropertyChanged("Count"); } }

        public void Increment()
        {
            Count++;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string prop)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;

            if (handler != null)
            {
                var e = new PropertyChangedEventArgs("prop");
                handler(this, e);
            }
        }
    };
}

Это связано с моим простым пользовательским интерфейсом в следующем XAML:

<Window x:Class="WpfModel.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="clr-namespace:WpfModel"
        Title="WPF Data Model Demo" Height="128" Width="284" >

    <Window.DataContext>
        <vm:AppModel />
    </Window.DataContext>

    <Grid Height="Auto" Width="Auto">
        <Button Margin="0,0,12,12" Name="IncButton" Height="23" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="75" Click="IncButton_Click" Content="Increment" />
        <Label Content="Count Variable:" Height="28" HorizontalAlignment="Left" Margin="12,12,0,0" Name="label1" VerticalAlignment="Top" />
        <Label Height="28" Margin="116,12,0,0" Name="CountLabel" VerticalAlignment="Top" HorizontalAlignment="Left" Width="40" Content="{Binding Path=Count}" />
    </Grid>
</Window>

Приложение определено следующим образом:

namespace WpfModel
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private AppModel _model = new AppModel();

        public MainWindow()
        {
            InitializeComponent();

            //_model = new AppModel();
        }

        private void IncButton_Click(object sender, RoutedEventArgs e)
        {
        }
    }
}

Когда приложение запускается, все выглядит превосходно, метка даже первоначально отображает любое значение, указанное в свойстве Count модели.Вызов increment корректно обновляет модель, и прямое приращение свойства Count, как показано в коде, также прекрасно работает.

Проблема здесь в том, что обработчик события PropertyChanged, кажется, никогда не добавляется.Я могу пройтись по коду в отладчике и увидеть значение в обновлении свойства, и я могу видеть даже вызов OnPropertyChanged, но сам обработчик PropertyChanged всегда равен null.

Есть ли проблема с моей привязкойвозможно?

Я использую MSVC 2010 Express.

Ответы [ 2 ]

8 голосов
/ 19 июня 2010

Проблема в том, что WpfModel, который у вас есть в качестве переменной экземпляра _model, равен , а не тем же экземпляром, который используется в качестве DataContext окна.Таким образом, он ничем не связан, и его PropertyChanged всегда будет иметь значение null.

Измените свой XAML для установки текста данных следующим образом:

<Window.DataContext>
            <vm:AppModel x:Name="_model" />
</Window.DataContext>

Избавьтесь от объявленной переменной экземплярав приведенном ниже коде и исправьте реализацию OnPropertyChanged (используйте параметр вместо буквальной строки «prop»), и это работает.

5 голосов
/ 19 июня 2010

эта строка:

var e = new PropertyChangedEventArgs("prop");

должна быть:

var e = new PropertyChangedEventArgs(prop);

Вы передаете строку «prop», поэтому связанные значения, прослушивающие «Count», не сработают.

** РЕДАКТИРОВАТЬ ** Основываясь на других ваших комментариях (ответ?), Я подумал, что лучше обновить это исправлением - вы, конечно, можете использовать уже полученный ответ, но я не хочу копировать кого-то еще :).

Добавьте это в ваш обработчик кликов:

((AppModel)this.DataContext).Count += 1;
...