[英]WPF - Programmatically set ComboBox Header/Text when selecting an item in a TreeView inside the ComboBox
In a UserControl I have a ComboBox with one hardcoded ComboBoxItem.在用户控件中,我有一个带有一个硬编码 ComboBoxItem 的 ComboBox。
The ComboBoxItem contains a TreeView. ComboBoxItem 包含一个 TreeView。
The content of the TreeView is set dynamically. TreeView的内容是动态设置的。
The content of each node in the TreeView are strings. TreeView中每个节点的内容都是字符串。
I would like to display the selected node's string in the header of the ComboBox.我想在 ComboBox 的 header 中显示所选节点的字符串。
I have tried many things and looked at many examples of TreeViews inside ComboBox, but cannot get this to work.我已经尝试了很多事情,并查看了 ComboBox 中的许多 TreeViews 示例,但无法使其正常工作。
Here is the source.这是来源。 I have removed all namespaces and other boiler-plate code.
我已经删除了所有命名空间和其他样板代码。
UserControl.xaml UserControl.xaml
<UserControl x:Class="Some.Namespace.TreeViewPopup"
xmlns:local="clr-namespace:Some.Namespace">
<ComboBox Name="cmbPopup" Grid.Column="1"
IsEditable="False"
Height="25">
<ComboBoxItem>
<TreeView Name="tvNodes"
Width="200"
Background="Transparent"
BorderThickness="0"
SelectedItemChanged="tvNodes_SelectedItemChanged">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Node}"
ItemsSource="{Binding Nodes}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</ComboBoxItem>
</ComboBox>
</UserControl>
UserControl.xaml.cs UserControl.xaml.cs
public partial class TreeViewPopup : UserControl
{
private Node SelectedNode { get; set; }
public TreeViewPopup()
{
InitializeComponent();
}
private void tvNodes_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
SelectedNode = tvNodes.SelectedItem as Node;
cmbPopup.Text = SelectedNode.Name;
}
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register
(
nameof(ItemsSource),
typeof(IEnumerable),
typeof(TreeViewPopup),
new PropertyMetadata(null, ItemsSourceChanged)
);
public IEnumerable ItemsSource
{
get => GetValue(ItemsSourceProperty) as IEnumerable;
set => SetValue(ItemsSourceProperty, value);
}
static void ItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue != e.OldValue && d is TreeViewPopup)
{
var instance = d as TreeViewPopup;
instance.tvNodes.ItemsSource = e.NewValue as IEnumerable;
}
}
}
Notice I have the property ItemsSource as custom DependencyProperty.请注意,我将属性 ItemsSource 作为自定义 DependencyProperty。 I'm going to populate the TreeView with this property.
我将使用此属性填充 TreeView。 for now I just hardcode a list in MainWindow.xaml.cs to this property.
现在我只是将 MainWindow.xaml.cs 中的列表硬编码到这个属性。
Node.cs节点.cs
public class Node
{
public string Name { get; set; }
public ObservableCollection<Node> Nodes { get; set; } = new ObservableCollection<Node>();
public override string ToString() => Name;
}
MainWindow.xaml主窗口.xaml
<Window x:Class="Some.Namespace.MainWindow">
<TreeViewPopup x:Name="ptv" Height="25" />
</Window>
MainWindow.xaml.cs主窗口.xaml.cs
public partial class MainWindow: Window
{
public PopupTreeView()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var a = new Node { Name = "A" };
var aa = new Node { Name = "AA" };
var ab = new Node { Name = "AB" };
var aaa = new Node { Name = "AAA" };
var aab = new Node { Name = "AAB" };
var aac = new Node { Name = "AAC" };
aa.Nodes.Add(aaa);
aa.Nodes.Add(aab);
aa.Nodes.Add(aac);
a.Nodes.Add(aa);
a.Nodes.Add(ab);
var b = new Node { Name = "B" };
var root = new Node { Name = "Root" };
root.Nodes.Add(b);
root.Nodes.Add(a);
var nodes = new ObservableCollection<Node>();
nodes.Add(root);
ptv.ItemsSource = root.Nodes;
}
}
This will give me a ComboBox with one ComboBoxItem containg the TreeView with all the nodes.这将给我一个 ComboBox 和一个包含所有节点的 TreeView 的 ComboBoxItem。
We I select a node in the TreeView the tvNodes_SelectedItemChanged
is called and I can "save" the selected node.我们我在 TreeView 中的一个节点
tvNodes_SelectedItemChanged
调用了 tvNodes_SelectedItemChanged,我可以“保存”选定的节点。
Here I try to set the ComboBox's Text
property to display the node's Name
property.这里我尝试设置 ComboBox 的
Text
属性来显示节点的Name
属性。
But this doesn't work.但这不起作用。 Instead the ComboBox displays the entire TreeView.
相反,ComboBox 显示整个 TreeView。 I assume it select the entire ComboBoxItem.
我假设它是 select 整个 ComboBoxItem。
Aany suggestions how to solve this? A任何建议如何解决这个问题?
/Steffe /斯蒂夫
Remove the ComboBoxItem
and define an ItemTemplate
:删除
ComboBoxItem
并定义一个ItemTemplate
:
<ComboBox Name="cmbPopup" Grid.Column="1"
IsEditable="False"
Height="25">
<ComboBox.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ComboBoxItem}}"
Value="{x:Null}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding SelectedItem.Name}" />
</DataTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</ComboBox.ItemTemplate>
<TreeView Name="tvNodes"
Width="200"
Background="Transparent"
BorderThickness="0"
SelectedItemChanged="tvNodes_SelectedItemChanged">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Node}"
ItemsSource="{Binding Nodes}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</ComboBox>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.