Выберите родительский ListBoxItem при взаимодействии с CheckBox - PullRequest
1 голос
/ 07 декабря 2011

Простой вопрос, хотя.У меня есть приложение WPF (.NET 4.0).Существует список, который содержит несколько пользовательских панелей.Каждая из этих пользовательских панелей содержит флажок.

Во время работы вы можете щелкнуть любую часть пользовательской панели, кроме самого флажка, и в списке будет выбрана эта строка (что визуально обозначается изменением фона в этом простом случае).Если вы отметите флажок, строка не будет выбрана.

Требование: если вы отметите флажок, это должно учитываться как выбор строки.

Контроль флажка:

<UserControl x:Class="CheckboxClickExample.CheckboxControl"
             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" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="189" d:DesignWidth="221">
    <Grid>
        <CheckBox Content="CheckBox" Height="16" HorizontalAlignment="Left" Margin="10,10,0,0" Name="checkBox1" VerticalAlignment="Top" />
    </Grid>
</UserControl>

Главное окно:

<Window x:Class="CheckboxClickExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:checkboxsample="clr-namespace:CheckboxClickExample"
        Title="MainWindow" Height="350" Width="525">
    <ListBox>        
        <checkboxsample:CheckboxControl/>
        <checkboxsample:CheckboxControl/>
        <checkboxsample:CheckboxControl/>
        <checkboxsample:CheckboxControl/>
    </ListBox>
</Window>

1 Ответ

2 голосов
/ 07 декабря 2011

Вы можете справиться с этим в вашем UserControl коде:

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        var parent = sender as DependencyObject;

        while (parent != null)
        {
            if (parent is Selector)
                break;

            parent = VisualTreeHelper.GetParent(parent);
        }

        if (parent != null)
            ((Selector) parent).SelectedItem = this;
    }

А затем используйте обработчик в вашем CheckBox:

<CheckBox Content="CheckBox"
          Height="16"
          Click="ButtonBase_OnClick"
          HorizontalAlignment="Left"
          Margin="10,10,0,0"
          VerticalAlignment="Top" />

Редактировать

Если вы не хотите использовать код позади, лучшее, что я думаю, вы можете сделать, это упаковать существующее решение как прикрепленное поведение. Преимущество этого заключается в том, что вам нужно написать код только один раз, а свойство можно установить для любой кнопки, даже если она не является частью UserControl.

Например:

public static class ButtonClickHelper
{
    public static void SetEnableSelectionOnClick(ButtonBase button, bool value)
    {
        button.SetValue(EnableSelectionOnClickProperty, value);
    }

    public static bool GetEnableSelectionOnClick(ButtonBase button)
    {
        return (bool) button.GetValue(EnableSelectionOnClickProperty);
    }

    public static readonly DependencyProperty EnableSelectionOnClickProperty =
        DependencyProperty.RegisterAttached("EnableSelectionOnClick", typeof (bool), typeof (ButtonClickHelper),
                                            new FrameworkPropertyMetadata(OnEnableSelectionOnClickPropertyChanged));

    private static void OnEnableSelectionOnClickPropertyChanged(DependencyObject d,
                                                                DependencyPropertyChangedEventArgs e)
    {
        if (!(d is ButtonBase))
            return;

        var button = (ButtonBase) d;
        if ((bool) e.NewValue)
        {
            button.Click += OnButtonClick;
        }
        else
        {
            button.Click -= OnButtonClick;
        }
    }

    private static void OnButtonClick(object sender, RoutedEventArgs e)
    {
        var parent = sender as DependencyObject;
        var ancestors = new List<DependencyObject>();

        while (parent != null)
        {
            if (parent is Selector)
                break;

            parent = VisualTreeHelper.GetParent(parent);
            ancestors.Add(parent);
        }

        if (parent != null)
        {
            var selector = (Selector) parent;
            var itemToSelect = ancestors.Where(i => selector.Items.Contains(i)).FirstOrDefault();

            if (itemToSelect != null)
                ((Selector) parent).SelectedItem = itemToSelect;
        }
    }
}

Затем вы можете использовать это в своем XAML, просто установив свойство зависимости EnableSelectionOnClick:

<CheckBox Content="CheckBox"
          Height="16"
          l:ButtonClickHelper.EnableSelectionOnClick="True"
          HorizontalAlignment="Left"
          Margin="10,10,0,0"
          VerticalAlignment="Top" />

Надеюсь, это поможет!

...