如何让复选框在 WPF 数据网格中工作

Posted

技术标签:

【中文标题】如何让复选框在 WPF 数据网格中工作【英文标题】:How can I get checkbox to work in WPF datagrid 【发布时间】:2015-08-05 21:08:27 【问题描述】:

我正在尝试向我的数据网格添加一个复选框列,以便用户可以轻松查看已选择的内容并轻松选择多个列,而无需知道如何使用 CTRL 按钮。有人介意帮忙吗?

如果已选中该复选框将取消选中,但单击它时无法使其变为选中状态。

<Window.Resources>
        <DataTemplate x:Key="isSelectedCheckBoxColumn">
                <CheckBox IsChecked="Binding Path=IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
      RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type DataGridRow">
                    <CheckBox.LayoutTransform>
                        <ScaleTransform ScaleX="1.5" ScaleY="1.5" />
                    </CheckBox.LayoutTransform>
                </CheckBox>
        </DataTemplate>
        <Style x:Key="RowStyleWithAlternation" TargetType="DataGridRow">
            <Setter Property="SnapsToDevicePixels" Value="True" />
            <Setter Property="Background" Value="GhostWhite"/>
            <Setter Property="FontWeight" Value="Normal"/>
            <Setter Property="ContextMenu" Value="x:Null"/>
            <Style.Triggers>
                <Trigger Property="AlternationIndex" Value="1">
                    <Setter Property="Background" Value="#C1FFC1"/>
                </Trigger>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="#F9F99F"/>
                </Trigger>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="LightBlue" />
                </Trigger>
                <Trigger Property="Validation.HasError" Value="True" >
                    <Setter Property="Effect">
                        <Setter.Value>
                            <DropShadowEffect Color="Red" ShadowDepth="0" BlurRadius="20" />
                        </Setter.Value>
                    </Setter>
                    <Setter Property="BorderThickness" Value="2" />
                    <Setter Property="BorderBrush" Value="Red" />
                    <Setter Property="Foreground" Value="Blue" />
                    <Setter Property="FontSize" Value="12" />
                </Trigger>
            </Style.Triggers>
        </Style>

        <Style x:Key="CenterCellStyle" TargetType="x:Type DataGridCell">
               <Setter Property="Template">
            <Setter.Value>
                    <ControlTemplate TargetType="x:Type DataGridCell">
                        <Grid>
                        <ContentPresenter HorizontalAlignment="center"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
            </Setter>
        </Style>

        <Style x:Key="RightCellStyle" TargetType="x:Type DataGridCell">
               <Setter Property="Template">
            <Setter.Value>
                    <ControlTemplate TargetType="x:Type DataGridCell">
                        <Grid>
                        <ContentPresenter HorizontalAlignment="Right"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>


                <DataGrid Grid.Row="1" AutoGenerateColumns="False" Name="grid_achCredit" RowStyle="StaticResource RowStyleWithAlternation" AlternationCount="2" FontSize="15" CanUserAddRows="False" CanUserDeleteRows="False" IsReadOnly="False" SelectionMode="Extended">
                    <DataGrid.Columns>
                        <DataGridTemplateColumn Header="" CellTemplate="StaticResource isSelectedCheckBoxColumn" IsReadOnly="False"/>
                        <DataGridTextColumn Header="ID" Width="Auto"  IsReadOnly="False" Binding="Binding ID" />
                        <DataGridTextColumn Header="TransDate" Width="Auto"  IsReadOnly="False" Binding="Binding transactionDate, StringFormat=\0:MM-dd-yyyy\" />
                        <DataGridTextColumn Header="Payor" Width="Auto"  IsReadOnly="False" Binding="Binding payer" />
                        <DataGridTextColumn Header="Description" Width="*"  IsReadOnly="False" Binding="Binding description" />
                        <DataGridTextColumn Header="Amount" Width="Auto"  IsReadOnly="False" Binding="Binding amount, StringFormat=C" />
                        <DataGridTextColumn Header="Balance" Width="Auto"  IsReadOnly="False" Binding="Binding amount, StringFormat=C" />
                        <DataGridTextColumn Header="Selected By" Width="*" IsReadOnly="False" Binding="Binding lockedUser"/>
                    </DataGrid.Columns>
                </DataGrid>

【问题讨论】:

【参考方案1】:

问题是当你点击CheckBox时,它的IsChecked属性和当前DataGridRowIsSelected属性设置为true同时。因此IsChecked 绑定无法按预期方式工作。

解决此问题的一种方法(可能不是最好的)是防止通过单击检查CheckBox(只允许取消选中)。这可以通过仅在选中 CheckBox 时启用:

        <CheckBox IsEnabled="Binding RelativeSource=RelativeSource Self, Path=IsChecked"
                    IsChecked="Binding Path=IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
                    RelativeSource=RelativeSource FindAncestor, AncestorType=x:Type DataGridRow">

所以这意味着您的CheckBox 仅在相应行被选中时才会被选中,但可以手动取消选中。

【讨论】:

不幸的是,这不允许用户使用复选框选择多行。但你确实帮助了我。我用我使用的解决方案发布了答案。【参考方案2】:

我最终决定使用行标题来设置复选框。这是我添加到数据网格中的代码

                    <DataGrid.RowHeaderTemplate>
                        <DataTemplate>
                            <Grid>
                                <CheckBox IsChecked="Binding Path=IsSelected, Mode=TwoWay,
                                      RelativeSource=RelativeSource FindAncestor,
                                      AncestorType=x:Type DataGridRow" Margin="0,-3,0,0">
                                    <CheckBox.LayoutTransform>
                                        <ScaleTransform ScaleX="2" ScaleY="2" />
                                    </CheckBox.LayoutTransform>
                                </CheckBox>
                            </Grid>
                        </DataTemplate>
                    </DataGrid.RowHeaderTemplate>

【讨论】:

嗯,这似乎是一个更好的解决方案,因为它更干净并且支持多选:)

以上是关于如何让复选框在 WPF 数据网格中工作的主要内容,如果未能解决你的问题,请参考以下文章

如何让 PROJ C++ 识别网格目录?

如何让我的存储过程在我的 Visual Studio 项目中工作?

如何让两种方式的数据绑定在 blazor 中工作?

如何获得动画 gif 以在 WPF 中工作?

Android:无法让 Checkbox OnClickListener 在 ListFragment 中工作

如何在 Datagrid WPF c# 中添加复选框