更新 UserControl 中 ItemsControl (ComboBox) 中的 SelectedItem
在选择 ComboBox
中的任何项目之前,其 SelectedItem
为 null,并且 ComboBox
本身在视觉上是空白的。一旦选择了某些内容,用户似乎没有任何方法可以选择“缺少选择”(尽管可以通过在代码中将 SelectedItem
设置为 null 来完成)。
我的 ComboBox 绑定到我的对象的 ObservableCollections。我不想在每个 ObservableCollection 的前面添加一个“特殊”的第一个类似 null 的对象。因此,我借此机会学习一些有关编写 UserControl 的知识。
问题是 SelectedItem
无法按正常方式工作。也就是说,ComboBox
很好地绑定到了一个支持 ObservableCollection
,但从 ComboBox
中选取某些内容不会更新 SelectedItem< /code> 它应该绑定到。
我觉得我需要将一些信息从用户控件中的组合框传递到...某个地方。我走在正确的轨道上吗?我应该用谷歌搜索什么?
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 :(
Before any item in a ComboBox
is selected, its SelectedItem
is null and the ComboBox
itself is visually blank. Once something is selected, there doesn't seem to be any way for the user to select "the absence of a selection" (though it can be done by setting SelectedItem
to null in code).
My ComboBoxes are bound to ObservableCollections of my objects. I don't want to add a "special" first null-like object to the front of every ObservableCollection. So I'm taking this opportunity to learn a bit about writing a UserControl.
The problem is SelectedItem
doesn't work the way it normally does. That is, the ComboBox
is nicely bound to a backing ObservableCollection
, but picking something from the ComboBox
doesn't update the SelectedItem
it's supposed to be bound to.
I feel like I need to be passing along some information from the ComboBox in the UserControl to...somewhere. Am I on the right track? What should I be googling for?
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>
Usage:
<wpfControl:ClearableComboBox ItemsSource="{Binding Path=Things}"
DisplayMemberPath="SomeProperty"
SelectedItem="{Binding Path=SelectedThing}" />
// Picking a Thing doesn't update SelectedThing :(
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
由于组合框派生自
Selector
类,而该类又派生自ItemsControl
。因此,通过从 UserControl 派生,您将避免使用 Selector 类的属性来组合框,该类可能会在内部为您处理选择的事情。所以,我建议您不要从 UserControl 派生它,而应该像这样从 Combobox 派生它 -因此,这样您就不必重写类中的
ItemsSource
、DisplayMemberPath 等,因为它已存在于ComboBox
类中。您始终可以进一步扩展您的类以提供附加功能,在您的情况下,在单击某些按钮时将SelectedItem
设置为 null。希望这就是您想要的。编辑(自定义控件)
创建自定义控件是您的答案,如果您不知道要开始,请查看此开始 - http://www.wpftutorial.net/HowToCreateACustomControl.html
当您创建自定义控件(例如 CustomControl1)时,替换模板为了CustomControl1 位于您的
Generic.xaml
文件中,默认情况下,您的
CustomControl1
类将从Control
派生。将其替换为从类ComboBox
派生,这样您就不必像这样再次声明 DP 并将此代码复制粘贴到那里 -现在,您的 CustomControl1 类已准备好在其他 xaml 文件中使用,例如这 -
Since combobox derives from
Selector
class which in turn derives fromItemsControl
. So, by deriving from UserControl you are devoiding your combobox with properties of Selector class which might internally handle the Selection thing for you. so, i would suggest instead of deriving it from UserControl, you should derive it from Combobox like this -So, that ways you won't have to override the
ItemsSource
, DisplayMemberPath etc. in your class since it s already present in theComboBox
class. You can always extend your class further to provide addidtional features which is in your case setting theSelectedItem
to null on some button click. Hope this is what you want..EDIT (Custom Control)
Creating a Custom Control is your answer here, to get started if you are not aware of it, look at this for start - http://www.wpftutorial.net/HowToCreateACustomControl.html
When you create a Custom Control say CustomControl1, replace the template for CustomControl1 in your
Generic.xaml
file with this one -By default your
CustomControl1
class will be derived fromControl
. Replace it to derive from classComboBox
so that you don't have declare DP's yet over again like this and copy paste this code there -Now, your CustomControl1 class is ready for use in your other xaml files like this -
我选择处理组合框上的按键事件并处理转义按键以清除组合框的
SelectedItem
。I chose to handle the key press event on the combo box and handle the escape key press to clear out the combo box's
SelectedItem
.我认为有更好的方法,为
ComboBox
开发一个包装器/装饰器,在ComboBox
旁边添加一个按钮并在单击时擦除选择。I think there's a better way, develop a wrapper/Adorner for
ComboBox
, that adds a button next to theComboBox
and wipe the selection on click.