复选框前带有文本的 DataGridCheckBoxColumn

DataGridCheckBoxColumn with text before the check box

我有一个 DataGrid 并且它有一个 DataGridCheckBox 列。我需要在 DataGrid:

的所有行中显示这样的复选框

下面是 XAML 和我的相应代码:

<!--MainWindow.xaml-->
<Window x:Class="DataGridColIssue.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" 
        Height="350" 
        Width="525"
        Loaded="Window_Loaded">

    <Window.Resources>
        <Style x:Key="RowNumberCheckBox" TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
            <Setter Property="FlowDirection" Value="RightToLeft"/>
            <Setter Property="VerticalAlignment" Value="Center"/>
            <Setter Property="HorizontalAlignment" Value="Center"/>
            <Setter Property="Content">
                <Setter.Value>
                    <Grid FlowDirection="LeftToRight">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="20"/>
                            <ColumnDefinition Width="5"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Grid.Column="0" Text="{Binding Number, StringFormat={}{0:00}}"/>
                    </Grid>
                </Setter.Value>
            </Setter>
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="30"/>
        </Grid.RowDefinitions>
        <DataGrid Grid.Row="0"
            Name="DataGridTesting"
                  AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridCheckBoxColumn Header="#"
                                        Binding="{Binding Exclude, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"
                                        ElementStyle="{StaticResource RowNumberCheckBox}"
                                        EditingElementStyle="{StaticResource RowNumberCheckBox}">
                </DataGridCheckBoxColumn>
            </DataGrid.Columns>
        </DataGrid>
        <Button Grid.Row="1"
                Name="AddItems"
                Content="Add Item"
                Click="AddItems_Click"/>
    </Grid>
</Window>

代码

//MainWindow.xaml.cs
using System.Collections.Generic;
using System.Windows;

namespace DataGridColIssue
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public int CurrentOperation;
        public List<Operation> Operations;
        public MainWindow()
        {
            InitializeComponent();
            Operations = new List<Operation>();
            CurrentOperation = 0;
        }

        private void AddItems_Click(object sender, RoutedEventArgs e)
        {
            CurrentOperation++;
            Operations.Add(new Operation(CurrentOperation));
            DataGridTesting.Items.Refresh();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
           DataGridTesting.ItemsSource = Operations;
           DataGridTesting.Items.Refresh();
        }
    }
}

操作class

namespace DataGridColIssue
{
    public class Operation
    {
        public bool Exclude { get; set; }
        public int Number { get; set; }

        public Operation(int Number)
        {
            this.Number = Number;
        }
    }
}

我遇到的问题是,只有最后添加的行与 CheckBox 之前的文本一起显示,看起来像这样:

如何让所有行在复选框前显示数字?

用作内容的网格实例由所有复选框共享。但它不能有多个父项,所以它显示在最后一个复选框中。

正确的方法是设置 ContentTemplate(从这个问题修改示例:Text on the left side of checkbox in WPF?, answer of nmclean

<Style x:Key="RowNumberCheckBox" TargetType="CheckBox" 
        BasedOn="{StaticResource {x:Type CheckBox}}">
    <Setter Property="Content" Value="{Binding Number}"/>
    <Setter Property="ContentStringFormat" Value="00"/>
    <Setter Property="FlowDirection" Value="RightToLeft" />
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <ContentControl Content="{Binding}" 
                                ContentStringFormat="{TemplateBinding ContentStringFormat}" />
            </DataTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="HorizontalContentAlignment" Value="Center"/>
    <Setter Property="VerticalContentAlignment" Value="Center"/>
    <Setter Property="HorizontalAlignment" Value="Center"/>
    <Setter Property="VerticalAlignment" Value="Center"/>
</Style>

您还注意到当 FlowDirection 为 RightToLeft 且选中 CheckBox 时复选标记被翻转了吗?

对于给定的要求,我的首选解决方案是 DataGridTemplateColumn 而不是 DataGridCheckBoxColumn 或者可能是带有文本和复选框的自定义 RowHeaderTemplate。

按照@Ash提供的解决方案,将Grid作为ContentTemplate的一部分,然后设置contentvalue,这样就可以了Grid 为每一行创建的实例,这里是产生期望结果的解决方案:

    <Style x:Key="RowNumberCheckBox" TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
        <Setter Property="FlowDirection" Value="RightToLeft"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
        <Setter Property="HorizontalAlignment" Value="Center"/>
        <Setter Property="Margin" Value="5"/>
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Grid FlowDirection="LeftToRight">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="20"/>
                            <ColumnDefinition Width="5"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Grid.Column="0" 
                                   Text="{Binding}"
                                   HorizontalAlignment="Right"/>
                    </Grid>
                </DataTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="Content" Value="{Binding Number}"/>
        <Setter Property="HorizontalContentAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
    </Style>