1

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.

Community
  • 1
  • 1
gregsdennis
  • 7,218
  • 3
  • 38
  • 71
  • 2
    You should not have CheckBoxes in a ComboBox in the first place. – H.B. Nov 14 '11 at 19:02
  • I agree with @H.B. a combobox shouldn't be multi-selectable. The reason is that there is then no standard way to close the combobox i.e. you have to find a different place to click to close it. Much better to have an expandable element of some sort to contain a simple listbox. – N_A Nov 14 '11 at 19:15
  • 1
    I've copied your solution to the blank wpf project, but I can't reproduce your problem: the popup remains open when I click checkboxes. It becames closed only if I click somewhere outside the combobox. – vortexwolf Nov 14 '11 at 19:23
  • @mydogisbox: As I stated this is not for multiple selection. This is for editing properties of the source objects. The ComboBox is a common interface element for users. This type of control is used in AutoCAD for basic editing of layers. – gregsdennis Nov 15 '11 at 13:30
  • @vortex, I will try it in a new solution. Maybe something else in my project is causing the problem. – gregsdennis Nov 15 '11 at 13:31
  • @gregsdennis: Could you just use a different non-ComboBox control? Then, define a `Popup` containing a `ListBox`. Define a `ListBox.ItemTemplate` with a `CheckBox`. – Jake Berger Nov 21 '11 at 18:04
  • @jberger, It sounds like you're wanting me to reinvent the `ComboBox`. I thought about doing that, but I figured there should be a better solution. – gregsdennis Nov 21 '11 at 18:43
  • @gregsdennis: There could very well be a simple, yet obscure boolean flag which is all that is needed. However, if .NET does not have an implemented solution, I'm merely pointing out a possibility... – Jake Berger Nov 21 '11 at 19:15
  • Focusable="False" really makes the trick, thanks – tomasK Oct 22 '15 at 11:48

2 Answers2

1

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.

vortexwolf
  • 13,967
  • 2
  • 54
  • 72
  • wow. Thanks. That _is_ messy. But I guess you have to do what's necessary to get it to work. I've started a new [question](http://stackoverflow.com/questions/8214948/wpf-combobox-in-toolbar-behaves-differently) to see if anyone can determine why it behaves differently. You may like to follow it. – gregsdennis Nov 21 '11 at 16:22
0

What you need is the Check ComboBox control, which is part of the WPF extended toolkit. You can find it here: Check ComboBox

d.moncada
  • 16,900
  • 5
  • 53
  • 82
  • The page says that this control is still under development. Also, that control is for multiple selection, not editing properties of the underlying data object. Thank you, though. – gregsdennis Nov 15 '11 at 14:54