在选择ComboBox
中的任何项目之前,其SelectedItem
为空,ComboBox
本身在视觉上为空白。一旦选择了某些内容,用户似乎没有任何方式可以选择“缺少选择”(尽管可以通过在代码中将SelectedItem
设置为null来完成。)
我的ComboBoxes绑定到我的对象的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 :(
答案 0 :(得分:1)
因为组合框来自Selector
类,而后者又来自ItemsControl
。因此,通过从UserControl派生,您将使用Selector类的属性来解除组合框,这可能会在内部为您处理Selection事物。所以,我建议而不是从UserControl派生它,你应该从这样的Combobox派生它 -
public partial class ClearableComboBox : ComboBox
因此,您可以通过这种方式覆盖类中的ItemsSource
,DisplayMemberPath等,因为它已经存在于ComboBox
类中。您可以随时进一步扩展您的类以提供附加功能,在您的情况下,在某些按钮单击时将SelectedItem
设置为null。希望这是你想要的......
编辑(自定义控制)
创建自定义控件是您的答案,如果您不了解它就开始使用,请先查看此内容 - 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"/>
答案 1 :(得分:0)
我选择在组合框上处理按键事件并按下转义按键以清除组合框的SelectedItem
。
答案 2 :(得分:0)
我认为有更好的方法,为ComboBox
开发一个包装器/装饰器,在ComboBox
旁边添加一个按钮,然后在点击时擦除选择。