使用绑定到 XDocument 的 DataContext 在 WPF TreeView 中设置 selectedItem
Set selectedItem in WPF TreeView with DataContext bound to XDocument
我的 WPF window 中有 TreeView。 TreeViews DataContext 绑定到 XDocument。
我正在寻找从后面的代码中设置 selectedItem 的方法。例如 .ItemContainerGenerator.Items 返回的节点是 System.Xml.Linq.XElement 类型而不是 System.Windows.Controls.TreeViewItem 我不能只设置 isSelected :-(
有人知道如何解决这个问题吗?
编辑:
XAML代码:
<Window.Resources>
<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="Root" FontFamily="Consolas" FontSize="8pt" />
<ItemsControl
ItemTemplate="{StaticResource AttributeTemplate}" HorizontalAlignment="Center"
ItemsSource="{Binding Converter={StaticResource AttrConverter}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
<HierarchicalDataTemplate.ItemsSource>
<Binding Path="Elements" />
</HierarchicalDataTemplate.ItemsSource>
<HierarchicalDataTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=NodeType}" Value="Element" />
<Condition Binding="{Binding Path=FirstNode.FirstNode.NodeType}" Value="Text" />
</MultiDataTrigger.Conditions>
<Setter TargetName="tbName" Property="Text" >
<Setter.Value>
<Binding Path="Name" />
</Setter.Value>
</Setter>
<Setter TargetName="tbName" Property="ToolTip">
<Setter.Value>
<MultiBinding Converter="{StaticResource MultiString2StringKonverter}">
<Binding Path="FirstNode.Value" />
<Binding Path="FirstNode.NextNode.Value" />
</MultiBinding>
</Setter.Value>
</Setter>
</MultiDataTrigger>
<DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
<Setter TargetName="tbName" Property="Text" Value="{Binding Path=Name}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=FirstNode.NodeType}" Value="Text">
<Setter TargetName="tbName" Property="Text">
<Setter.Value>
<MultiBinding StringFormat="{}{0} = {1}">
<Binding Path="Name"/>
<Binding Path="FirstNode.Value"/>
</MultiBinding>
</Setter.Value>
</Setter>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</Window.Resources>
<TreeView x:Name="LizenzAnsicht"
ItemsSource="{Binding Path=Root.Elements, UpdateSourceTrigger=PropertyChanged}"
ItemTemplate="{StaticResource ResourceKey=NodeTemplate}"
/>
隐藏代码:
...
LizenzAnsicht.DataContext = XDocument.Load(<Path to XML-File>);
在为此睡了一个周末之后,我自己找到了答案。还有一些问题,因为只有 return 类型。
解决方法是,为Item获取匹配的ItemContainer。这个Container是TreeViewItem类型的,我可以在这里设置isSelected之类的。
作为一个例子在大多数情况下更容易理解,我举一个例子。以下函数将搜索 TreeView- 对象中的 XML- 节点和包含匹配节点的 return TreeViewItem。如果未找到匹配项,则 returned 为 null。
匹配的节点被展开。
XML 在绑定到 System.Windows.Controls.TreeView DataContext 的 System.Xml.linq.XDocument 中处理。
调用函数时 TreeView 设置为 ic.
public static TreeViewItem SearchNodeInTreeView(ItemsControl ic, XElement NodeDescription, string indent = "")
{
TreeViewItem ret = null;
foreach (object o in ic.Items)
{
if (o is XElement)
{
var x = ic.ItemContainerGenerator.ContainerFromItem(o);
if (XNode.DeepEquals((o as XElement), NodeDescription))
{
ret = x as TreeViewItem;
}
else if ((o as XElement).HasElements){
if (x != null)
{
bool expanded = (x as TreeViewItem).IsExpanded;
(x as TreeViewItem).IsExpanded = true;
(x as TreeViewItem).UpdateLayout();
ret = SearchNodeInTreeView (x as TreeViewItem, NodeDescription, indent + " ");
if (ret == null)
{
(x as TreeViewItem).IsExpanded = expanded;
(x as TreeViewItem).UpdateLayout();
}
}
}
}
if (ret != null)
{
break;
}
}
return ret;
}
我希望我能帮助任何人。
我的 WPF window 中有 TreeView。 TreeViews DataContext 绑定到 XDocument。
我正在寻找从后面的代码中设置 selectedItem 的方法。例如 .ItemContainerGenerator.Items 返回的节点是 System.Xml.Linq.XElement 类型而不是 System.Windows.Controls.TreeViewItem 我不能只设置 isSelected :-(
有人知道如何解决这个问题吗?
编辑: XAML代码:
<Window.Resources>
<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="Root" FontFamily="Consolas" FontSize="8pt" />
<ItemsControl
ItemTemplate="{StaticResource AttributeTemplate}" HorizontalAlignment="Center"
ItemsSource="{Binding Converter={StaticResource AttrConverter}}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</StackPanel>
<HierarchicalDataTemplate.ItemsSource>
<Binding Path="Elements" />
</HierarchicalDataTemplate.ItemsSource>
<HierarchicalDataTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=NodeType}" Value="Element" />
<Condition Binding="{Binding Path=FirstNode.FirstNode.NodeType}" Value="Text" />
</MultiDataTrigger.Conditions>
<Setter TargetName="tbName" Property="Text" >
<Setter.Value>
<Binding Path="Name" />
</Setter.Value>
</Setter>
<Setter TargetName="tbName" Property="ToolTip">
<Setter.Value>
<MultiBinding Converter="{StaticResource MultiString2StringKonverter}">
<Binding Path="FirstNode.Value" />
<Binding Path="FirstNode.NextNode.Value" />
</MultiBinding>
</Setter.Value>
</Setter>
</MultiDataTrigger>
<DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
<Setter TargetName="tbName" Property="Text" Value="{Binding Path=Name}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=FirstNode.NodeType}" Value="Text">
<Setter TargetName="tbName" Property="Text">
<Setter.Value>
<MultiBinding StringFormat="{}{0} = {1}">
<Binding Path="Name"/>
<Binding Path="FirstNode.Value"/>
</MultiBinding>
</Setter.Value>
</Setter>
</DataTrigger>
</HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>
</Window.Resources>
<TreeView x:Name="LizenzAnsicht"
ItemsSource="{Binding Path=Root.Elements, UpdateSourceTrigger=PropertyChanged}"
ItemTemplate="{StaticResource ResourceKey=NodeTemplate}"
/>
隐藏代码: ...
LizenzAnsicht.DataContext = XDocument.Load(<Path to XML-File>);
在为此睡了一个周末之后,我自己找到了答案。还有一些问题,因为只有 return 类型。
解决方法是,为Item获取匹配的ItemContainer。这个Container是TreeViewItem类型的,我可以在这里设置isSelected之类的。
作为一个例子在大多数情况下更容易理解,我举一个例子。以下函数将搜索 TreeView- 对象中的 XML- 节点和包含匹配节点的 return TreeViewItem。如果未找到匹配项,则 returned 为 null。 匹配的节点被展开。 XML 在绑定到 System.Windows.Controls.TreeView DataContext 的 System.Xml.linq.XDocument 中处理。 调用函数时 TreeView 设置为 ic.
public static TreeViewItem SearchNodeInTreeView(ItemsControl ic, XElement NodeDescription, string indent = "")
{
TreeViewItem ret = null;
foreach (object o in ic.Items)
{
if (o is XElement)
{
var x = ic.ItemContainerGenerator.ContainerFromItem(o);
if (XNode.DeepEquals((o as XElement), NodeDescription))
{
ret = x as TreeViewItem;
}
else if ((o as XElement).HasElements){
if (x != null)
{
bool expanded = (x as TreeViewItem).IsExpanded;
(x as TreeViewItem).IsExpanded = true;
(x as TreeViewItem).UpdateLayout();
ret = SearchNodeInTreeView (x as TreeViewItem, NodeDescription, indent + " ");
if (ret == null)
{
(x as TreeViewItem).IsExpanded = expanded;
(x as TreeViewItem).UpdateLayout();
}
}
}
}
if (ret != null)
{
break;
}
}
return ret;
}
我希望我能帮助任何人。