我有一个问题.我在我的
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="="" Foreground="{StaticResource xmlMarkBrush}" FontFamily="Consolas" FontSize="8pt" /> <TextBlock Text="{Binding Path=Value,Mode=TwoWay}" Foreground="{StaticResource xmlValueBrush}" FontFamily="Consolas" FontSize="8pt" /> <TextBlock Text=""" 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; }