在CheckBox交互时选择父ListBoxItem

时间:2011-12-07 00:29:55

标签: wpf wpf-controls

虽然简单的问题。我有一个WPF应用程序(.NET 4.0)。有一个列表框,其中包含许多用户面板。每个用户面板都包含一个复选框。

运行时,您可以单击userpanel的任何部分,但复选框本身除外,列表框将选择该行(在这个简单的情况下,通过背景变化可视地指示)。如果选中该框,则未选中该行。

要求: 如果选中该复选框,则应将其视为选择行。

复选框控件:

<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 个答案:

答案 0 :(得分:2)

您可以在后面的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;
        }
    }
}

然后,您可以通过设置EnableSelectionOnClick依赖项属性

在XAML中使用它
<CheckBox Content="CheckBox"
          Height="16"
          l:ButtonClickHelper.EnableSelectionOnClick="True"
          HorizontalAlignment="Left"
          Margin="10,10,0,0"
          VerticalAlignment="Top" />

希望这有帮助!