【问题标题】:OnPropertyChanged does not update the ViewOnPropertyChanged 不更新视图
【发布时间】:2016-07-26 10:51:20
【问题描述】:

我有一个 ListView,它的 itemsource 指向 Elements,这是一个 Schranken-Objects 列表。 SchrankePresenter 是页面的 DataContext(在构造函数中设置)。

页面显示正确,直到单击按钮。如果单击按钮,则按钮的值 Name 应更改,并且 ListView 应多出一项,但没有任何反应/更新。

这是 SchrankenPresenter:

 public class SchrankePresenter : INotifyPropertyChanged
    {
        private List<Schranke> _elements;
        public List<Schranke> Elements
        {
            get { return _elements; }
            set
            {
                _elements = value;
                OnPropertyChanged("Elements");
            }
        }
        public ICommand ClickCommand { get; set; }
    private void OnPropertyChanged(string propName)
    {
        Debug.WriteLine($"on Property changed with {propName}");
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public SchrankePresenter()
    {
        var elements = new List<Schranke>();
        for (var i = 1; i < 15; i++)
            elements.Add(new Schranke() { Name = $"{i}: Schranke" });

        Elements = elements;
        Debug.WriteLine("ctor");
        ClickCommand = new DelegateCommand<Schranke>(ClickAction);
    }

    public void ClickAction(Schranke item)
    {
        VibrationDevice.GetDefault().Vibrate(TimeSpan.FromMilliseconds(150));

        Debug.WriteLine($"{item?.Name} was clicked");
        item.Name = "was clicked";
        OnPropertyChanged("Name");
        Elements.Add(new Schranke() { Name = "addednew element" });
        OnPropertyChanged("Elements");

    }

}

Schranke 类只有一个成员:public string Name { get; set; }

视图如下:

 <ListView ItemsSource="{Binding Elements, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="lv_schranken" Grid.Row="1" SelectedItem="{Binding  SelectedItem}">

            <ListView.ItemTemplate>
                <DataTemplate>
                    <Button Height="80"
                            HorizontalAlignment="Stretch"
                            Command="{Binding ElementName=lv_schranken, Path=DataContext.ClickCommand}"
                            CommandParameter="{Binding}"
                            Style="{StaticResource TransparentStyle}">
                        <Grid>
                                .
                                .  (some grid stuff)
                                .

                            <TextBlock Name="schranken_name"
                                       Grid.Row="1"
                                       Grid.Column="1"
                                       HorizontalAlignment="Center"
                                       VerticalAlignment="Center"
                                       FontWeight="ExtraLight"
                                       FontSize="25"
                                       Foreground="Black"
                                       Text="{Binding Name, Mode=TwoWay}" />
                        </Grid>
                    </Button>
                </DataTemplate>

            </ListView.ItemTemplate>

        </ListView>

PS:如果有些人需要 DelegateCommand - 实现:

 public class DelegateCommand<T> : ICommand
    {
    private Action<T> _clickAction;

    public DelegateCommand(Action<T> clickAction)
    {
        _clickAction = clickAction;
    }

    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        _clickAction((T)parameter);
    }
}

【问题讨论】:

  • OnPropertyChanged("Name"); 应该在 Schranke 类中调用,在 Name 设置器中。
  • 如果您进行过任何研究,您就会知道没有绑定到List&lt;T&gt;
  • 难道不能使用 List 进行绑定吗?
  • 是的,但你不应该这样做;它效率低下,本质上是一种黑客攻击。
  • 那么 ObservableCollection 会是更好的方法吗?

标签: wpf xaml data-binding inotifypropertychanged


【解决方案1】:

如果你想绑定到列表项,你应该绑定到ObservableCollection

表示一个动态数据集合,它在何时提供通知 添加、删除或刷新整个列表时。

https://msdn.microsoft.com/de-de/library/ms668604(v=vs.110).aspx

【讨论】:

    【解决方案2】:

    为了从Viewmodel 更新用户界面,我们需要提出inotifypropertychangedobservablecollection 默认提供inotifypropertychanged 实现;我们可以参考observablecollection 获取MVVm pattern

    如果您想使用相同的列表,那么您需要在该特定列表上实现inotifypropertychanged

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-13
      • 1970-01-01
      • 2022-01-13
      • 2019-06-30
      • 2021-02-13
      • 1970-01-01
      • 1970-01-01
      • 2016-08-30
      相关资源
      最近更新 更多