我正在开发一个 WPF 项目,目前它实现了
ComboBox
、Button
、ICommand
和 TreeView
。 TreeView
是通过绑定到 ICommand
的 Button
接口生成的。运行应用程序时,从 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();
}
这是否与我通过
ObservableCollection<ParentNew> FamilyList
接口清除并重写属性ICommand
有关?
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; }
}
我期待更新的
FamilyList
属性显示在窗口上,同时在展开树并单击 Button
后保持其结构。
值得注意的是,如果
TreeViewItem.IsExpanded
设置为 False
,not 手动展开并单击 Button
,则 TreeView
会保持其结构并更新后的 Children
。
当我在 xaml 中将 TreeViewItem.IsExpanded
设置为 True
时,即使我是第一次运行该应用程序,TreeView 也不会显示 Children
。 TreeViewItem.IsExpanded
是否触发了我看不到的东西?
目前我没有使用任何后台代码,而且我也不打算这样做。我对 C# 语言和 WPF 也相当陌生,因此我尝试通过阅读有关该主题的几篇 StackOverflow 帖子来寻找答案,但没有成功。我缺少什么?预先感谢。
您分配了 Children 集合 (
parent.Children = children;
),但 UI 现在不支持这一点。
为了确保 UI 更新,请在 ParentNew 类中实现 INotifyPropertyChange 接口并引发 PropertyChange 事件。
但还有一个简单的修复方法 - 在将父对象添加到 FamilyList 之前分配集合:
ObservableCollection<ChildNew> children = new ObservableCollection<ChildNew>();
parent.Children = children;
FamilyList.Add(parent);
foreach (var r in RoomsToShow)
{
if (r.Position == a.Position)
{
ChildNew child = new ChildNew();
child.Name = r.Name;
children.Add(child);
}
}