所以,假设我有一个带有自定义数据模板的ComboBox。数据模板中的一个项目是按钮:
<ComboBox Width="150" ItemsSource="{Binding MyItems}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Button Content="ClickMe" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
这个问题是按钮会点击,如果选择按钮,项目就不会被选中。这意味着下拉菜单不会消失,也不会选择任何项目。
我知道为什么会发生这种情况。
有办法解决这个问题吗?可能是一种处理按钮单击的方法(我绑定到一个命令)并告诉它继续向上链,这样组合框也可以处理点击?
注意:我在Silverlight中看到了我的问题,但我猜测WPF可以看到完全相同的行为。
答案 0 :(得分:8)
<ComboBox x:Name="MyCombo" Width="150" ItemsSource="{Binding MyItems}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Button Content="ClickMe" Click="Button_Click" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
在后面的代码中:
private void Button_Click(object sender, RoutedEventArgs e)
{
MyCombo.SelectedItem = (sender as Button).DataContext;
MyCombo.IsDropDownOpen = false;
}
如果我真的想要,我可以将SelectedItem和IsDropDownOpen绑定到我的ViewModel中的属性,但我决定将此行为保留为XAML的黑客扩展,以保持我的ViewModel清洁。
答案 1 :(得分:1)
您最好的选择可能是在按钮的命令中设置SelectedItem。
答案 2 :(得分:1)
我发现了MVVM上下文的另一种可能性。我使用了ComboBox
的派生类,如果某个项是adden,派生自ButtonBase
,我会附加到Click
事件以关闭ComboBox
。
这适用于我的项目 - 但是,因为项目本身就是按钮,如果它们只包含按钮作为子元素,它将无法工作。
public class MyComboBox : ComboBox
{
public MyComboBox()
{
// use Loaded event to modify inital items.
Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
if (Items != null)
{
foreach (var item in Items)
{
var button = item as ButtonBase;
if (button != null)
{
ModifyButtonItem(button);
}
}
}
}
protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);
// Check added items. If an item is a button, modify the button.
if (e.NewItems != null)
{
foreach (var item in e.NewItems)
{
var button = item as ButtonBase;
if (button != null)
{
ModifyButtonItem(button);
}
}
}
}
private void ModifyButtonItem(ButtonBase button)
{
button.Click += (sender, args) => { IsDropDownOpen = false; };
}
}
答案 3 :(得分:0)
我不知道是否有办法做你想做的事。例如,如果您在Button
中放置ListBox
,则会出现相同的行为 - 点击Button
不会导致ListBox
中的项目被选中。实际上,支持选择的ItemsControl
中的任何控件都是这种情况。
您可以对Click
事件执行某些操作并将其标记为未处理,以便它继续显示在可视树中,但即便如此,我也不确定这是否有效。