2012-08-16 139 views
6

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

这里是我的树的模板:

<DataTemplate x:Key="AttributeTemplate"> 
    <StackPanel Orientation="Horizontal" 
      Margin="3,0,0,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 
} 

的第二件事是,如何清除我的树,以便能够再次用于其它数据(我有NullReferenceException试图XmlTree.Items.Clear();

回答

11

后几个小时终于找到了解决方案!

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; 
} 
+4

男人你是最棒的!我需要这些神奇的线条: XmlTree.Items.Refresh(); XmlTree.UpdateLayout(); 非常感谢,解决了我的问题! – Alex 2013-05-03 08:54:22

+0

Yeee,他们可以让别人紧张:) – Nickon 2013-05-03 12:33:40