我正在开发一个WPF项目,目前实现了ComboBox
,Button
,ICommand
和TreeView
。TreeView
通过绑定到Button
的ICommand
接口生成。在运行应用程序时,从ComboBox
中选择项目并单击Button
后,我的TreeView将按预期显示。xaml:
<Window.Resources>
<vm:RevitVM x:Key="viewmodel"/>
<HierarchicalDataTemplate DataType="{x:Type vm:ParentNew}"
ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type vm:ChildNew}">
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</Window.Resources>
<Grid DataContext="{StaticResource viewmodel}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="6*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="1">
<ComboBox ItemsSource="{Binding UniqueAreaTypes}"
SelectedItem="{Binding SelectedAreaType}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding AreaType}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
<Button Content="Search"
Command="{Binding SearchCommand}"
Grid.Row="5"
Grid.Column="0"
Margin="4"/>
<TreeView
Grid.Row="1"
Grid.Column="1">
<TreeViewItem ItemsSource="{Binding FamilyList}" Header="Test"
IsExpanded="False"/>
</TreeView>
</Grid>
当展开TreeView并第二次使用Button
时(无论选择了ComboBox
项),就会出现问题。我的TreeView
只显示更新的父项,而不显示Children
。看起来好像绑定丢失了。
public RevitVM()
{
SearchCommand = new SearchCommand(this);
FamilyList = new ObservableCollection<ParentNew>();
}
public void SetTree()
{
FamilyList.Clear();
foreach (var a in AreasToShow)
{
ParentNew parent = new ParentNew();
parent.Name = a.Name;
FamilyList.Add(parent);
ObservableCollection<ChildNew> children = new ObservableCollection<ChildNew>();
foreach (var r in RoomsToShow)
{
if (r.Position == a.Position)
{
ChildNew child = new ChildNew();
child.Name = r.Name;
children.Add(child);
}
}
parent.Children = children;
}
}
public void MakeQuery()
{
SetTree();
}
这是否与我通过ICommand
接口清除并重写属性ObservableCollection<ParentNew> FamilyList
有关?
public class SearchCommand : ICommand
{
public RevitVM VM { get; set; }
public SearchCommand(RevitVM revitVM)
{
VM = revitVM;
}
public event EventHandler? CanExecuteChanged;
public bool CanExecute(object? parameter)
{
return true;
}
public void Execute(object? parameter)
{
VM.MakeQuery();
}
ParentNew
类:
public class ParentNew
{
public string Name { get; set; }
public int Id { get; set; }
public ObservableCollection<ChildNew> Children { get; set; }
}
我希望在展开树并单击Button
后,更新后的FamilyList
属性会显示在Window上,同时保持其结构。
值得注意的是,如果TreeViewItem.IsExpanded
被设置为False
,不手动展开并单击Button
,则TreeView
将保持其结构,并更新Children
。当我在xaml中将TreeViewItem.IsExpanded
设置为True
时,即使我第一次运行应用程序,TreeView也不会显示Children
。TreeViewItem.IsExpanded
是否触发了我无法看到的内容?
目前我没有使用任何代码背后,我不打算。我对C#语言和WPF也是相当陌生的,所以我试图通过阅读几篇关于这个主题的StackOverflow文章来寻找答案,但无济于事。我错过了什么?先谢了。
1条答案
按热度按时间nr9pn0ug1#
你分配了Children集合(
parent.Children = children;
),但是UI不知道。要确保UI已更新,请在ParentNew类中实现INotifyPropertyChanged接口并引发PropertyChanged事件。
但是在将父对象添加到FamilyList之前,还有一个简单的fix - assign集合: