WPF TreeView 刷新
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11986840/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF TreeView refreshing
提问by Nickon
I've got a problem. I use TreeViewin my WPF project to visualize my XML data. The problem is, when I edit my XmlDocumentit doesn't refresh in TreeView. But I noticed that when I check SelectedNode, it is my editted and XmlNode. So my "Edit" method works fine, but there's only a problem in visual refresh of my tree. .Refresh()or .Items.Refresh()don't work either.
我有问题。我TreeView在我的 WPF 项目中使用来可视化我的 XML 数据。问题是,当我编辑XmlDocument它时,它不会在TreeView. 但我注意到,当我检查时SelectedNode,它是我的编辑和XmlNode. 所以我的“编辑”方法工作正常,但我的树的视觉刷新只有一个问题。.Refresh()或者.Items.Refresh()也不工作。
Here's the template of my tree:
这是我的树的模板:
<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="=""
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>
Here are Window.Resources:
这里是Window.Resources:
<Window.Resources>
<XmlDataProvider x:Key="XmlData" />
</Window.Resources>
Here's my tree:
这是我的树:
<TreeView x:Name="XmlTree" Grid.Row="1"
ItemsSource="{Binding Source={StaticResource XmlData}, XPath=., Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemTemplate="{StaticResource NodeTemplate}"
SelectedItemChanged="XmlTree_SelectedItemChanged" />
And here's my code behind:
这是我的代码:
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
}
The second thing is, how to clear my tree in order to be able to use it again for another data (I've got NullReferenceExceptionwhile trying XmlTree.Items.Clear();
第二件事是,如何清除我的树以便能够再次将其用于其他数据(我NullReferenceException在尝试时得到了XmlTree.Items.Clear();
回答by Nickon
After many hours finally found a solution!
几个小时后终于找到了解决方案!
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;
}
回答by B_Manx
For some reason nothing under the sun worked for me and all I needed was to refresh an image on my tree if that item was changed. so I did something ridiculous but worked great. First I added a Loaded event to my image and I set the Tag as the unique id of the record from the database
出于某种原因,太阳底下没有任何东西对我有用,如果该项目发生更改,我所需要的只是刷新树上的图像。所以我做了一些可笑但效果很好的事情。首先,我向我的图像添加了一个 Loaded 事件,并将 Tag 设置为数据库中记录的唯一 ID
Tag="{Binding ObjectId}" Loaded="imgCheckComment_Loaded"
in the codebehind on that loaded event I built a list of every image
在加载事件的代码隐藏中,我构建了每个图像的列表
private List<Image> commentColors = new List<Image>();
private void imgCheckComment_Loaded(object sender, RoutedEventArgs e)
{
var si = sender as Image;
if (si != null)
commentColors.Add(si);
}
then any time I made a change to anything I updated the Image property of Item (Item is the custom class I bound to my tree) I brute force updated the object
然后每当我对任何内容进行更改时,我都会更新 Item 的 Image 属性(Item 是我绑定到我的树的自定义类),我会蛮力更新该对象
public void RefreshContext(Item selectedItem)
{
commentColors.ForEach(si => {
if (selectedItem.ObjectId == Convert.ToInt32(si.Tag))
{
si.Source = new BitmapImage(new Uri(selectedItem.Image, UriKind.Relative));
return;
}
});
}

