带复选框的ComboBox在复选框单击时关闭 [英] ComboBox with Checkboxes closes on Checkbox Click

查看:197
本文介绍了带复选框的ComboBox在复选框单击时关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个问题,但提供的解决方案无效,也没有任何其他我发现。我要创建一个 ComboBox CheckBox es作为 ItemTemplate 。这已经完成。但是当用户单击复选框时,会出现问题: PopUp 关闭。我需要它保持开放。



我尝试处理 ComboBox.SelectionChanged 事件和 CheckBox.Click 事件,但我不能得到它。从跟踪代码看,当用户单击 CheckBox 时,SelectionChanged事件不会触发,这与控件的行为相匹配,因为没有显示任何内容 TextBox 部分。



这不是多重选择,



以下是一些示例代码

 < Toolbar VerticalAlignment =Top> 
< ComboBox x:Name =comboBoxSelectionChanged =ComboBox_SelectionChanged>
< ComboBox.ItemTemplate>
< DataTemplate DataType =local:MyType>
< Grid>
< Grid.ColumnDefinitions>
< ColumnDefinition Width =Auto/>
< ColumnDefinition />
< /Grid.ColumnDefinitions>
< CheckBox Click =CheckBox_Clicked/>
< TextBlock Text ={Binding Title}Grid.Column =1/>
< / Grid>
< / DataTemplate>
< /ComboBox.ItemTemplate>
< local:MyType Title =item 1/>
< local:MyType Title =item 2/>
< local:MyType Title =item 3/>
< local:MyType Title =item 4/>
< / ComboBox>
< / Toolbar>

private void ComboBox_SelectionChanged(object sender,SelectionChangedEventArgs e)
{
//做一些东西
}

private void CheckBox_Clicked发送者,RoutedEventArgs e)
{
//如果没有数据绑定就改变数据上下文的属性

//尝试这个,但Popup刚关闭然后重新打开
comboBox.IsDropDownOpen = true;
//这似乎没有效果
e.Handled = true;
}

任何人都可以帮助?



编辑:



我注意到,当 ComboBox 放置在工具栏中。当不在工具栏中时,它的行为与预期的一致: CheckBox 更改状态而不关闭弹出。但在 ToolBar 中, Popup 在第一次点击时关闭,无论点击在哪里。请尝试新的代码。



对于后代来说,和任何人搜索它, MS建议将DataTemplate中CheckBox的Focusable属性设置为false。

似乎工具栏控制以某种方式影响 ComboBox 控件。奇怪的是,当你将光标放在 TextBox 中时, ComboBox code>。Checkbox 。



解决此问题的最快方法是在用户单击复选框
我使用以下顺序的步骤:



1)处理每个控件的 GotFocus 应用程序



2)仅保留复选框控制

的事件

3)检查 CheckBox 是否在当前 ComboBox



4)如果是,将焦点返回 ComboBox

  public MainWindow()
{
InitializeComponent();

// ...

comboBox.AddHandler(FrameworkElement.GotFocusEvent,(RoutedEventHandler)OnGotFocus);
}

private void OnGotFocus(object sender,RoutedEventArgs e)
{
if(e.OriginalSource是CheckBox)
{
var comboBox =(ComboBox)sender;
var comboBoxItem = GetParentElement< ComboBoxItem>(e.OriginalSource);

if(comboBoxItem!= null&& comboBox.Items.OfType< object>()。select(comboBox.ItemContainerGenerator.ContainerFromItem).Contains(comboBoxItem))
comboBox.Focus ();
}
}

private T GetParentElement< T>(object element)其中T:DependencyObject
{
var current = element as DependencyObject;

while(current!= null&&!(current is T))
{
current = VisualTreeHelper.GetParent(current);
}

返回电流为T;
}

这是一个相当混乱的解决方案,

I have this same problem, but the solution presented isn't working, nor is any other I've found. I want to create a ComboBox with CheckBoxes as part of the ItemTemplate. This has been accomplished. But the problem arises when the user clicks a CheckBox: the PopUp closes. I need it to stay open.

I tried handling the ComboBox.SelectionChanged event and the CheckBox.Click event, but I can't get it. From tracing through the code, it appears that the SelectionChanged event doesn't fire at all when the user clicks the CheckBox, which is matches the behavior of the control as nothing appears in the TextBox portion.

This is not for multiple selection, but rather to have the CheckBox bind to a property in the data context.

Here is some sample code

<Toolbar VerticalAlignment="Top">
    <ComboBox x:Name="comboBox" SelectionChanged="ComboBox_SelectionChanged">
        <ComboBox.ItemTemplate>
            <DataTemplate DataType="local:MyType">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <CheckBox Click="CheckBox_Clicked"/>
                    <TextBlock Text="{Binding Title}" Grid.Column="1"/>
                </Grid>
            </DataTemplate>
        </ComboBox.ItemTemplate>
        <local:MyType Title="item 1"/>
        <local:MyType Title="item 2"/>
        <local:MyType Title="item 3"/>
        <local:MyType Title="item 4"/>
    </ComboBox>
</Toolbar>

private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    // do some stuff
}

private void CheckBox_Clicked(object sender, RoutedEventArgs e)
{
    // change a property on the data context if not data bound

    // Tried this, but Popup just closes then reopens
    comboBox.IsDropDownOpen = true;
    // This seems to have no effect
    e.Handled = true;
}

Can anyone help?

EDIT:

I noticed that there is a difference of behavior when the ComboBox is placed in a Toolbar. When not in the Toolbar, it behaves as expected: the CheckBox changes state without closing the Popup. But in the ToolBar, the Popup closes on the first click, regardless of where the click is. Try the new code, please. I really need this in a toolbar.

EDIT 2:

For posterity and anyone searching for it, MS suggested setting the Focusable property of the CheckBox in the DataTemplate to false. This achieves the desired effect.

解决方案

It seems that the Toolbar control affects the ComboBox control in some way. And strangely, the ComboBox isn't closed when you put the cursor inside the TextBox, but works wrong with the CheckBox.

The quickest way to solve this issue is to change focus manually when a user clicks the CheckBox. I use the following sequence of steps:

1) Handle the GotFocus event for every control in the application

2) Leave only events of the CheckBox control

3) Check whether the CheckBox is inside the current ComboBox

4) If yes, return focus to the ComboBox

    public MainWindow()
    {
        InitializeComponent();

        //...

        comboBox.AddHandler(FrameworkElement.GotFocusEvent, (RoutedEventHandler)OnGotFocus);
    }

    private void OnGotFocus(object sender, RoutedEventArgs e)
    {
        if (e.OriginalSource is CheckBox)
        {
            var comboBox = (ComboBox)sender;
            var comboBoxItem = GetParentElement<ComboBoxItem>(e.OriginalSource);

            if (comboBoxItem != null && comboBox.Items.OfType<object>().Select(comboBox.ItemContainerGenerator.ContainerFromItem).Contains(comboBoxItem))
                comboBox.Focus();
        }
    }

    private T GetParentElement<T>(object element) where T : DependencyObject
    {
        var current = element as DependencyObject;

        while (current != null && !(current is T))
        {
            current = VisualTreeHelper.GetParent(current);
        }

        return current as T;
    }

It is a quite messy solution, but anyway it works.

这篇关于带复选框的ComboBox在复选框单击时关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆