我有一个简单的例子,其背后的代码就像这样
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中只有第一级才能正确更新,而子级别是emty 。如果我将INotifyPropertyChanged添加到SubItems属性,TreeView的子级也会正确更新。有人可以告诉我这个吗?
答案 0 :(得分:0)
当您的窗口打开时,它会开始处理来自Items
集合的所有数据。一旦完成,就无法对物品进行某种通知。更改窗口以查看数据已更改且内容将更新。所以,在INotifyPropertyChanged
和它的堂兄INotifyCollectionChanged
来获取帮助。
您也可以考虑将ListBox。ItemsSource
重置为null并返回Items - 这将有效地使控件重新处理数据并重新呈现内容。
答案 1 :(得分:0)
在VS2015上再次检查VS2013,不能重复说明中的问题。假设它是一些外部条件,而不是代码。 无论如何,对于来自@AlexSeleznyov的谈话=)