分层数据模板是否需要 InotifyProperty更改了可观察集合类型的属性



我有一个简单的例子,其中后面的代码是这样的

using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
namespace WpfApplication7
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public ObservableCollection<Item> Items { get; set; }
        public MainWindow()
        {
            Items = new ObservableCollection<Item>();
            InitializeComponent();
        }
        private void ButtonBase1_OnClick(object sender, RoutedEventArgs e)
        {
            Items.Add(new Item() { ItemName = DateTime.Now.ToString(), SubItems = new ObservableCollection<string>() {"1"} });
        }
        private void ButtonBase2_OnClick(object sender, RoutedEventArgs e)
        {
            var f = Items.FirstOrDefault();
            if (f!=null)
                f.SubItems.Add(f.SubItems.Count.ToString());
        }
    }
    public class Item
    {
        public string ItemName { get; set; }
        public ObservableCollection<string> SubItems { get; set; }
    }
}

和XAML是这样的

<Window x:Class="WpfApplication7.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication7"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"  DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <StackPanel>
        <TreeView ItemsSource="{Binding Path=Items}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding SubItems}">
                    <TextBlock Text="{Binding ItemName}"></TextBlock>
                   <HierarchicalDataTemplate.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding}"></TextBlock>
                        </DataTemplate>
                    </HierarchicalDataTemplate.ItemTemplate>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
        <ListBox ItemsSource="{Binding Path=Items}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding ItemName}"></TextBlock>
                        <ListBox ItemsSource="{Binding SubItems}">
                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding}"></TextBlock>
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                        </ListBox>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button Click="ButtonBase1_OnClick">321</Button>
        <Button Click="ButtonBase2_OnClick">123</Button>
    </StackPanel>
</Window>

我仍然不清楚为什么行为不同- ListBoxes在两个集合中的每一个小变化都被更新(假设为ObservableCollection)。但是在TreeView中只有第一个级别被正确更新,而子级别不断为空。如果我将INotifyPropertyChanged添加到SubItems属性,则TreeView的子级别也会正确更新。有人能告诉我吗?

当窗口打开时,它开始处理来自Items集合的所有数据。一旦完成,除了在Items的更改上发出某种通知之外,没有办法让窗口看到数据已经更改,内容也要更新。所以,INotifyPropertyChanged和它的表亲INotifyCollectionChanged来帮忙了。

你也可以考虑重置ListBox。

ItemsSource设置为null并返回Items -这将有效地使控件重新处理数据并重新呈现内容。

在VS2013和VS2015上检查一次,不能重复描述中的问题。假设它是某种外部条件,而不是代码。无论如何,感谢@AlexSeleznyov的对话=)

最新更新