【问题标题】:INotifyPropertyChanged PropertyChanged event remains null [closed]INotifyPropertyChanged PropertyChanged 事件保持为空 [关闭]
【发布时间】:2020-05-11 18:00:14
【问题描述】:

我在论坛上搜索了一些关于 PropertyChanged 事件的其他资源仍然为空,但没有找到任何解决方案。我用 AModel、AViewModel 和 MainWindow 创建了一个示例 WPF 应用程序。 Model 和 ViewModel 已实现 INotifyPropertyChanged 接口,但在运行时检查时,两个 PropertyChanged 事件都保持为空。申请代码如下:

public class AModel : INotifyPropertyChanged
{
    public AModel()
    {

    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string propertyname = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
        }
    }
    private string _A;
    public string A
    {
        get
        {
            return _A;
        }
        set
        {
            _A = value;
            NotifyPropertyChanged("A");
        }
    }
}

public class AViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string propertyname = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
        }
    }
    public AViewModel()
    {
        MyList = new List<AModel>();

    }

    private List<AModel> _MyList;
    public List<AModel> MyList
    {
        get
        {
            return _MyList;
        }
        set
        {
            _MyList = value;
        }
    }


}

public partial class MainWindow : Window
{
    private AViewModel _objViewModel=new AViewModel();
    public AViewModel ObjViewModel
    {
        get
        {
            return _objViewModel;
        }
        set
        {
            _objViewModel = value;
        }
    }
    public MainWindow()
    {
        InitializeComponent();
        ObjViewModel = new AViewModel();
        DataContext = ObjViewModel;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        ObjViewModel.MyList.Add(new AModel() { A = "Sample Text" });
    }
}

现在,当我向模型类 PropertyChanged 事件添加断点时,它始终为空。我已经创建了视图模型对象并将其分配给 MainWindow 的 DataContext 但仍然为空。我无法理解在这个简单的应用程序中哪里出错了。我检查了绑定是否正常工作。

提前致谢

【问题讨论】:

  • 你在视图中用MyList做什么?只要视图没有绑定到该集合的 AModel 元素的属性,它的 PropertyChanged 事件当然会为空。为了使ObjViewModel.MyList.Add 更新视图,请使用ObservableCollection,即public ObservableCollection&lt;AModel&gt; MyList
  • @Clemens MyList 用于与 MainWindow 中的 DataGrid 绑定,并且 AModel 属性 A 与该 datagrid 列绑定。我知道 observable 集合,但我想找出如果 DataContext 被分配给 MainWindow,属性更改事件仍然为 null 的问题。

标签: .net wpf mvvm data-binding inotifypropertychanged


【解决方案1】:

PropertyChanged 事件在此处为空,因为该属性实际上并未发生更改。您正在创建一个集合,然后将其绑定到一个 UI 控件。如果你想看到一个属性改变被触发,那么你可以试试这个:-

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="auto" />
        </Grid.RowDefinitions>
        <DataGrid Margin="20" AutoGenerateColumns="True" ItemsSource="{Binding MyList}"/>
        <ListBox Grid.Row="1" ItemsSource="{Binding MyList}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding A,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button  Grid.Row="2" HorizontalAlignment="Center" Margin="20" Content="Click Me" Click="Button_Click"/>
    </Grid>

所以,当您尝试更新文本框中的项目时:-

<DataTemplate>
                    <TextBox Text="{Binding A,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>

然后您会注意到,一旦您在 TextBox 中键入,就会触发更改的属性:-

{Method = {Void OnPropertyChanged(System.Object, System.ComponentModel.PropertyChangedEventArgs)}}

如果您需要更多说明,请发表评论。

【讨论】:

  • 解释完全错误。 PropertyChanged 事件是 not null 只是因为 UI 中的属性未更改。它肯定是空的,因为没有绑定。我之所以说最肯定,是因为我们没有看到 XAML,也无法确定。无论如何,请注意 UpdateSourceTrigger=PropertyChanged 与 INotifyPropertyChanged 接口的 PropertyChanged 事件没有任何关系。这是两个不同的东西,意外地同名。
  • 是的。 UpdateSourceTrigger 与更改的属性无关。在这种情况下,调用 ObjViewModel.MyList.Add(new AModel() { A = "Sample Text" }); PropertyChanged 为 null,因为 Binding 仍然不存在。它只是创建了一个普通的 POCO,因此 PropertyChanged 为空。但是当绑定已经存在时,会附加一个 PropertyChanged,这就是它可以工作的原因。我提供的示例说明了这一点。 @Clemens 只注意到 PropertyChanged 而不是解决方案,这很糟糕。
  • 所以,Pankaj,当您没有可用的绑定时,不会触发已更改的属性。在您的情况下,您提到您将它绑定到 DataGrid 并且它显示正常,但是,它是在将项目添加到列表之后。 PropertyChanged 事件在 UI 中显示后被附加。在我给出的示例中,我在呈现 UI 后在模板中更新它,因此 PropertyChanged 不为空。更新源触发器只提到何时更新属性,立即或失去焦点或显式,每个控件都有默认方式。
  • @Clemens,关于您的评论“PropertyChanged 事件不是空的,只是因为 UI 中的属性没有更改。它肯定是空的,因为没有绑定。”即使存在绑定,更改的属性最初也可以为 null。呈现控件时附加事件 PropertyChanged。呈现控件后,属性的任何更改都将具有不为 null 的 PropertyChanged 事件。
猜你喜欢
  • 1970-01-01
  • 2018-11-19
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
  • 2010-12-03
  • 2019-12-25
  • 2016-04-17
  • 2011-06-30
相关资源
最近更新 更多