ComboBox с флажками закрывается при нажатии флажка - PullRequest
1 голос
/ 14 ноября 2011

У меня такая же та же проблема, но представленное решение не работает, как и любой другой, который я нашел.Я хочу создать ComboBox с CheckBox как часть ItemTemplate.Это было достигнуто.Но проблема возникает, когда пользователь нажимает CheckBox: PopUp закрывается.Мне нужно, чтобы он оставался открытым.

Я пытался обработать события ComboBox.SelectionChanged и CheckBox.Click, но не могу его получить.Из трассировки кода видно, что событие SelectionChanged вообще не срабатывает, когда пользователь щелкает CheckBox, что соответствует поведению элемента управления, поскольку в части TextBox ничего не появляется.

Это не для множественного выбора, а для привязки CheckBox к свойству в контексте данных.

Вот пример кода

<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;
}

Кто-нибудь может помочь?

РЕДАКТИРОВАТЬ:

Я заметил, что есть разница в поведении, когда ComboBox помещается в Toolbar.Когда он не в Toolbar, он ведет себя как ожидалось: CheckBox меняет состояние, не закрывая Popup.Но в ToolBar, Popup закрывается при первом щелчке, независимо от того, где находится щелчок.Попробуйте новый код, пожалуйста.Мне действительно нужно это на панели инструментов.

РЕДАКТИРОВАТЬ 2:

Для потомков и тех, кто его ищет, MS предложила установить свойство Focusable дляCheckBox в шаблоне данных в false.Это достигает желаемого эффекта.

Ответы [ 2 ]

1 голос
/ 16 ноября 2011

Кажется, что элемент управления Toolbar так или иначе влияет на элемент управления ComboBox. И как ни странно, ComboBox не закрывается, когда вы помещаете курсор внутрь TextBox, но работает неправильно с CheckBox.

Самый быстрый способ решить эту проблему - изменить фокус вручную, когда пользователь нажимает CheckBox. Я использую следующую последовательность шагов:

1) Обработка события GotFocus для каждого элемента управления в приложении

2) Оставлять только события элемента управления CheckBox

3) Проверьте, находится ли CheckBox внутри текущего ComboBox

4) Если да, верните фокус на 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;
    }

Это довольно грязное решение, но в любом случае оно работает.

0 голосов
/ 15 ноября 2011

Вам нужен элемент управления Check ComboBox, который является частью расширенного инструментария WPF. Вы можете найти его здесь: Проверьте ComboBox

...