如何在WPF DataGrid中实现单击复选框选择?

161

我有一个DataGrid,第一列是文本列,第二列是复选框列。我的目标是,如果我点击复选框,它应该被选中。

但是,需要点击两次才能选中,在第一次单击时,单元格会被选中,第二次单击时复选框才会被选中。如何使复选框在一次单击时被勾选/取消勾选。

我使用的是WPF 4.0。 DataGrid中的列是自动生成的。


4
重复:https://dev59.com/AnM_5IYBdhLWcg3wymc0,但这个标题更好。 - surfen
12个回答

1

这里提供一种方法,使用自己的列类来扩展默认的DataGridCheckBoxColumn类,并且可以像普通列一样使用。只需复制/粘贴即可。

public class DataGridCheckBoxColumn : System.Windows.Controls.DataGridCheckBoxColumn
{
    private static Style _noFocusEditElementStyle;

    static DataGridCheckBoxColumn()
    {
        ElementStyleProperty.OverrideMetadata(typeof(DataGridCheckBoxColumn), new FrameworkPropertyMetadata(NoFocusEditElementStyle));
        EditingElementStyleProperty.OverrideMetadata(typeof(DataGridCheckBoxColumn), new FrameworkPropertyMetadata(NoFocusEditElementStyle));
    }


    protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
    {
        base.OnPropertyChanged(e);

        if (e.Property.Name == nameof(IsReadOnly))
        {
            ElementStyle = IsReadOnly ? DefaultElementStyle : NoFocusEditElementStyle;
            EditingElementStyle = IsReadOnly ? DefaultElementStyle : NoFocusEditElementStyle;
        }
    }

    public static Style NoFocusEditElementStyle
    {
        get
        {
            if (_noFocusEditElementStyle == null)
            {
                Style style = new Style(typeof(System.Windows.Controls.CheckBox));

                // When not in edit mode, the end-user should not be able to toggle the state
                style.Setters.Add(new Setter(UIElement.FocusableProperty, false));
                style.Setters.Add(new Setter(System.Windows.Controls.CheckBox.HorizontalAlignmentProperty, HorizontalAlignment.Center));
                style.Setters.Add(new Setter(System.Windows.Controls.CheckBox.VerticalAlignmentProperty, VerticalAlignment.Top));

                style.Seal();
                _noFocusEditElementStyle = style;
            }

            return _noFocusEditElementStyle;
        }
    }
}

使用读/写属性:

<myNamespace:DataGridCheckBoxColumn Header="Name"
                    Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />

只读属性的使用:

<myNamespace:DataGridCheckBoxColumn Header="Name"
                    IsReadOnly="True"
                    Binding="{Binding Name, Mode=OneWay}" />

说明:

  • 默认列类有两个样式属性,一个用于编辑模式,一个用于查看模式。
  • 在只读情况下,我们在两种情况下都使用查看样式
  • 在其他情况下,在编辑模式下设置编辑样式
  • 我更喜欢使用不会获得焦点的复选框样式(NoFocusEditElementStyle),因为这种行为看起来有点奇怪,而不是使用EditElementStyle

1
<Style x:Key="StilCelula" TargetType="DataGridCell"> 
<Style.Triggers>
 <Trigger Property="IsMouseOver" Value="True">
   <Setter Property="IsEditing" 
     Value="{Binding RelativeSource={x:Static RelativeSource.Self}, 
     Converter={StaticResource CheckBoxColumnToEditingConvertor}}" />
 </Trigger>
</Style.Triggers>
<Style>

Imports System.Globalization
Public Class CheckBoxColumnToEditingConvertor
    Implements IValueConverter
    Public Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As CultureInfo) As Object Implements IValueConverter.Convert
        Try

            Return TypeOf TryCast(value, DataGridCell).Column Is DataGridCheckBoxColumn
        Catch ex As Exception
            Return Visibility.Collapsed
        End Try
    End Function

    Public Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As CultureInfo) As Object Implements IValueConverter.ConvertBack
        Throw New NotImplementedException()
    End Function
End Class

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接