正在更新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 :(

正在更新UserControl中ItemsControl(组合框)中的SelectedItem

因为组合框派生自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旁边添加一个按钮,并在单击时擦除所选内容。