![](/img/trans.png)
[英]Maintaining combobox text after selecting a bound item in WPF / C#
[英]WPF - Programmatically set ComboBox Header/Text when selecting an item in a TreeView inside the ComboBox
在用户控件中,我有一个带有一个硬编码 ComboBoxItem 的 ComboBox。
ComboBoxItem 包含一个 TreeView。
TreeView的内容是动态设置的。
TreeView中每个节点的内容都是字符串。
我想在 ComboBox 的 header 中显示所选节点的字符串。
我已经尝试了很多事情,并查看了 ComboBox 中的许多 TreeViews 示例,但无法使其正常工作。
这是来源。 我已经删除了所有命名空间和其他样板代码。
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
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;
}
}
}
请注意,我将属性 ItemsSource 作为自定义 DependencyProperty。 我将使用此属性填充 TreeView。 现在我只是将 MainWindow.xaml.cs 中的列表硬编码到这个属性。
节点.cs
public class Node
{
public string Name { get; set; }
public ObservableCollection<Node> Nodes { get; set; } = new ObservableCollection<Node>();
public override string ToString() => Name;
}
主窗口.xaml
<Window x:Class="Some.Namespace.MainWindow">
<TreeViewPopup x:Name="ptv" Height="25" />
</Window>
主窗口.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;
}
}
这将给我一个 ComboBox 和一个包含所有节点的 TreeView 的 ComboBoxItem。
我们我在 TreeView 中的一个节点tvNodes_SelectedItemChanged
调用了 tvNodes_SelectedItemChanged,我可以“保存”选定的节点。
这里我尝试设置 ComboBox 的Text
属性来显示节点的Name
属性。
但这不起作用。 相反,ComboBox 显示整个 TreeView。 我假设它是 select 整个 ComboBoxItem。
A任何建议如何解决这个问题?
/斯蒂夫
删除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.