正在更新UserControl中ItemsControl(组合框)中的SelectedItem
本文关键字:组合 中的 SelectedItem ItemsControl 更新 UserControl | 更新日期: 2023-09-27 18:12:34
在选择ComboBox
中的任何项目之前,其SelectedItem
为空,而ComboBox
本身在视觉上为空。一旦选择了某个内容,用户似乎就没有任何方法来选择"没有选择"(尽管可以通过在代码中将SelectedItem
设置为null来完成(。
我的组合框绑定到我的对象的ObservableCollections。我不想在每个ObservableCollection的前面添加一个"特殊"的第一个类似null的对象。因此,我借此机会学习一些关于编写UserControl的知识。
问题是SelectedItem
不能正常工作。也就是说,ComboBox
很好地绑定到一个后备ObservableCollection
,但从ComboBox
中挑选一些东西并不能更新它应该绑定到的SelectedItem
我觉得我需要把一些信息从UserControl中的ComboBox传递到…某个地方。我走对了吗?我应该在谷歌上搜索什么?
C#:
public partial class ClearableComboBox : UserControl
{
public ClearableComboBox()
{
InitializeComponent();
}
public IEnumerable ItemsSource
{
get { return (IEnumerable)base.GetValue(ItemsSourceProperty); }
set { base.SetValue(ItemsSourceProperty, value); }
}
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource",
typeof(IEnumerable),
typeof(ClearableComboBox));
public object SelectedItem
{
get { return (object)base.GetValue(SelectedItemProperty); }
set { base.SetValue(SelectedItemProperty, value); }
}
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register("SelectedItem",
typeof(object),
typeof(ClearableComboBox));
public string DisplayMemberPath
{
get { return (string)base.GetValue(DisplayMemberPathProperty); }
set { base.SetValue(DisplayMemberPathProperty, value); }
}
public static readonly DependencyProperty DisplayMemberPathProperty =
DependencyProperty.Register("DisplayMemberPath",
typeof(string),
typeof(ClearableComboBox));
private void Button_Click(object sender, RoutedEventArgs e)
{
comboBox.SelectedItem = null;
}
}
XAML:
<UserControl x:Class="MyProj.ClearableComboBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="root">
<DockPanel>
<Button DockPanel.Dock="Left" Click="Button_Click" ToolTip="Clear">
<Image Source="pack://application:,,,/img/icons/silk/cross.png" Stretch="None" />
</Button>
<ComboBox
Name="comboBox"
ItemsSource="{Binding ElementName=root, Path=ItemsSource}"
SelectedItem="{Binding ElementName=root, Path=SelectedItem}"
DisplayMemberPath="{Binding ElementName=root, Path=DisplayMemberPath}" />
</DockPanel>
</UserControl>
用法:
<wpfControl:ClearableComboBox ItemsSource="{Binding Path=Things}"
DisplayMemberPath="SomeProperty"
SelectedItem="{Binding Path=SelectedThing}" />
// Picking a Thing doesn't update SelectedThing :(
因为组合框派生自Selector
类,而CCD_10又派生自CCD11。因此,通过从UserControl派生,您可以使用Selector类的属性来开发组合框,Selector类可能会在内部为您处理Selection。因此,我建议您不要从UserControl派生它,而应该从这样的组合框派生它-
public partial class ClearableComboBox : ComboBox
因此,这样就不必重写类中的ItemsSource
、DisplayMemberPath等,因为它已经存在于ComboBox
类中。您总是可以进一步扩展您的类以提供附加功能,在您的情况下,单击某个按钮时将SelectedItem
设置为null。希望这是你想要的。。
EDIT(自定义控制(
创建自定义控件是您的答案,要开始,如果您没有意识到,请查看此开始-http://www.wpftutorial.net/HowToCreateACustomControl.html
当您创建自定义控件(比如CustomControl1(时,将Generic.xaml
文件中的CustomControl1模板替换为以下模板-
<ControlTemplate TargetType="{x:Type local:CustomControl1}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<DockPanel>
<Button Name="btn" DockPanel.Dock="Left" ToolTip="Clear" Width="20">
<Image Source="pack://application:,,,/img/icons/silk/cross.png" Stretch="None" />
</Button>
<ComboBox Name="comboBox"
ItemsSource="{TemplateBinding ItemsSource}"
SelectedItem="{TemplateBinding SelectedItem}"
DisplayMemberPath="{TemplateBinding DisplayMemberPath}" />
</DockPanel>
</Border>
</ControlTemplate>
默认情况下,CustomControl1
类将从Control
派生。将其替换为从类ComboBox
派生,这样您就不必像这样再次声明DP,并将此代码复制粘贴到那里-
public class CustomControl1 : ComboBox
{
private Button clearButton;
private ComboBox comboBox;
static CustomControl1()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
clearButton = GetTemplateChild("btn") as Button;
comboBox = GetTemplateChild("comboBox") as ComboBox;
clearButton.Click += new RoutedEventHandler(clearButton_Click);
}
private void clearButton_Click(object sender, RoutedEventArgs e)
{
comboBox.SelectedItem = null;
}
}
现在,您的CustomControl1类已准备好在其他xaml文件中使用,如
<local:CustomControl1 ItemsSource="{Binding YourSource}"
SelectedItem="{Binding YourSelectedItem}"
Height="50" Width="200"/>
我选择处理组合框上的按键事件,并处理escape按键以清除组合框的SelectedItem
。
我认为有一个更好的方法,为ComboBox
开发一个包装器/Adorner,在ComboBox
旁边添加一个按钮,并在单击时擦除所选内容。