C# · 12月 28, 2021

c# – WPF TreeView刷新

我有一个问题.我在我的 WPF项目中使用TreeView来可视化我的 XML数据.问题是,当我编辑我的XmlDocument时,它不会在TreeView中刷新.但是我注意到当我检查SelectedNode时,它是我的编辑和XmlNode.所以我的“编辑”方法工作正常,但我的树的视觉刷新只有一个问题. .Refresh()或.Items.Refresh()也不起作用.

这是我树的模板:

<DataTemplate x:Key=”AttributeTemplate”> <StackPanel Orientation=”Horizontal” Margin=”3,0″ HorizontalAlignment=”Center”> <TextBlock Text=”{Binding Path=Name}” Foreground=”{StaticResource xmAttributeBrush}” FontFamily=”Consolas” FontSize=”8pt” /> <TextBlock Text=”=&quot;” Foreground=”{StaticResource xmlMarkBrush}” FontFamily=”Consolas” FontSize=”8pt” /> <TextBlock Text=”{Binding Path=Value,Mode=TwoWay}” Foreground=”{StaticResource xmlValueBrush}” FontFamily=”Consolas” FontSize=”8pt” /> <TextBlock Text=”&quot;” Foreground=”{StaticResource xmlMarkBrush}” FontFamily=”Consolas” FontSize=”8pt” /> </StackPanel></DataTemplate><HierarchicalDataTemplate x:Key=”NodeTemplate”> <StackPanel Orientation=”Horizontal” Focusable=”False”> <TextBlock x:Name=”tbName” Text=”?” FontFamily=”Consolas” FontSize=”8pt” /> <ItemsControl ItemTemplate=”{StaticResource AttributeTemplate}” ItemsSource=”{Binding Path=Attributes}” HorizontalAlignment=”Center”> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation=”Horizontal”/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> </StackPanel> <HierarchicalDataTemplate.ItemsSource> <Binding XPath=”*” /> </HierarchicalDataTemplate.ItemsSource> <HierarchicalDataTemplate.Triggers> <DataTrigger Binding=”{Binding Path=NodeType}” Value=”Text”> <Setter TargetName=”tbName” Property=”Text” Value=”{Binding Path=Value,Mode=TwoWay}”/> </DataTrigger> <DataTrigger Binding=”{Binding Path=NodeType}” Value=”Element”> <Setter TargetName=”tbName” Property=”Text” Value=”{Binding Path=Name}”/> </DataTrigger> </HierarchicalDataTemplate.Triggers></HierarchicalDataTemplate><Style x:Key=”TreeViewAllExpandedStyle” TargetType=”{x:Type TreeView}”> <Style.Resources> <Style TargetType=”TreeViewItem”> <Setter Property=”IsExpanded” Value=”True” /> </Style> </Style.Resources></Style><Style x:Key=”TreeViewAllCollapsedStyle” TargetType=”{x:Type TreeView}”> <Style.Resources> <Style TargetType=”TreeViewItem”> <Setter Property=”IsExpanded” Value=”False” /> </Style> </Style.Resources></Style>

这是Window.Resources:

<Window.Resources> <XmlDataProvider x:Key=”XmlData” /></Window.Resources>

这是我的树:

<TreeView x:Name=”XmlTree” Grid.Row=”1″ ItemsSource=”{Binding Source={StaticResource XmlData},XPath=.,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}” ItemTemplate=”{StaticResource NodeTemplate}” SelectedItemChanged=”XmlTree_SelectedItemChanged” />

这是我的代码背后:

private XmlDocument _xml;private XmlElement _selectedElement;private XmlDataProvider _xmlDataProvider;private void MainWindow_Load(object sender,EventArgs e){ XmlTree.Style = (Style)FindResource(“TreeViewAllExpandedStyle”); _xmlDataProvider = FindResource(“XmlData”) as XmlDataProvider;}private void OpenXmlFile(string filePath){ _xml = new XmlDocument(); _xml.Load(filePath); _xmlDataProvider.Document = _xml;}private void SaveChangesButton_Click(object sender,EventArgs e){ Dictionary<string,string> newAttributes = GetChangedAttributes(); foreach (KeyValuePair<string,string> pair in newAttributes) { _selectedElement.SetAttribute(pair.Key,pair.Value); } RefreshViews();}private void RefreshViews(){ // Now I don’t kNow what to do here,any Refresh doesn’t work:S}

第二件事是,如何清除我的树以便能够再次使用它来获取另一个数据(我在尝试XmlTree.Items.Clear()时遇到了NullReferenceException;

解决方法 经过几个小时终于找到了解决方案! private void RefreshViews(){ XmlEditor.Clear(); XmlEditor.Text = IndentXml(); UnselectSelectedItem(); XmlTree.Items.Refresh(); XmlTree.UpdateLayout();}private void UnselectSelectedItem(){ if (XmlTree.SelectedItem != null) { var container = FindTreeViewSelectedItemContainer(XmlTree,XmlTree.SelectedItem); if (container != null) { container.IsSelected = false; } }}private static TreeViewItem FindTreeViewSelectedItemContainer(ItemsControl root,object selection){ var item = root.ItemContainerGenerator.ContainerFromItem(selection) as TreeViewItem; if (item == null) { foreach (var subItem in root.Items) { item = FindTreeViewSelectedItemContainer((TreeViewItem)root.ItemContainerGenerator.ContainerFromItem(subItem),selection); if (item != null) { break; } } } return item;}