WPF Datagrid:基于复选框条件为所有行禁用一行中的另一个单元格

WPF Datagrid: based on checkbox condition disable another cell in a row for all the rows

我用 AutoGenerateColumns = false 开发了自定义数据网格,在后面的代码中,我根据需要的类型创建了列。我用过

DataGridTemplateColumn 对于 string 类型(具有 cellTemplate 和 CellEditing 模板)和复选框类型,我使用了 DataGridCheckBoxColumn.

现在我的要求是,在数据网格中,如果用户选中了 2 个以上的复选框(即每一行只有一个复选框,每行复选框的点击次数为一次),那么特定的列应为所有行禁用类型为文本框的名称 "DisplayName"。

我已经创建了一个 属性 来维护 checkBoxClicked 的计数,并且它已根据复选框的选中或取消选中进行了正确更新,现在我想使用这个 属性 并禁用所有未选中复选框且仅针对列名 "DisplayName".

的行

任何建议都会有所帮助。

已编辑:

我已经在代码中尝试了以下内容,但它不起作用。为 DataGridCell 创建了样式。并添加了一个转换器,它检查我试图禁用的列名称,下面是示例代码

<Style x:Key="DataGridCellStyle1" TargetType="{x:Type DataGridCell}">
<DataTrigger Binding="{Binding ElementName=DataGridUserControl, Path=MaxAddToLabelReached}" Value="true">
         <Setter Property="IsEnabled" Value="{Binding Path=Value, Converter={StaticResource ValueToBrushConverter}}" />
</DataTrigger>

我的转换器有逻辑

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 {

   try
   {
     DataGridCell dgc = (DataGridCell)value;

     if (dgc.Column.Header.ToString().Equals("Display Name"))
       return false;

   }
   catch (InvalidCastException )
   {
     return Boolean.FalseString;
   }


   return Boolean.TrueString;
 }

要求:

我的要求是 - 如果我有十行,那么每一行都会有一个名称为 AddtoLabel 的复选框类型列,在同一行中还会有一个名称为 "Display name" 的列,当用户检查复选框,然后复选框的计数将是一个,如果复选框的计数超过两个,那么我的 属性 "MaxAddToLabelReached" 将设置为 true.Means 我不应该允许用户检查其他行中未选中的复选框。我创建了一种样式来禁用所有其他未选中的复选框,因此未选中的 "Addtolabel" 列复选框将被禁用,

这工作正常。在 "MaxAddToLabelReached" 然后在 "Displayname" 列中,我必须以相同的方式检查未选中复选框的行,如果未选中,则禁用 "DisplayName" 列该特定行的单元格。

已编辑:

我为数据网格创建列的方式是

我在 XAML 中创建了一个模板,如下所示

<DataGridTemplateColumn Header="CellTempalte" x:Key="DataGridTemplateColumn">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate x:Name="DataGridCellTemplateColumn">
      <TextBlock  x:Name="textBlock" DataContextChanged="Cell_DataContextChanged" Margin="0, 0"  Loaded="Cell_Loaded" VerticalAlignment="Top"  
                  >

      </TextBlock>
            </DataTemplate>              
        </DataGridTemplateColumn.CellTemplate>
        <DataGridTemplateColumn.CellEditingTemplate>
            <DataTemplate x:Name="DataGridCellEditTemplateColumn">
                <TextBox   x:Name="celltext"  DataContextChanged="T_Cell_DataContextChanged" VerticalContentAlignment="Top" MinHeight="20" VerticalAlignment="Stretch" MouseEnter="datagrid_CellTextBoxEnter" 
                           MouseLeftButtonDown="TextBox_MouseLeftButtonDown_1" BorderBrush="{x:Null}" BorderThickness="0"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellEditingTemplate>
    </DataGridTemplateColumn>

在初始化列后面的代码中,我创建了如下列

       if (columnType == "Text")
        {

           DataGridTemplateColumn dataGridTemplateColumnForText = this.FindResource("DataGridTemplateColumn") as        DataGridTemplateColumn;
           DataGrid.Columns.Add(new DataGridTemplateColumn()
           {
              Header = columnHeadersInfo.colHeaderConfigInfoColl[i].nlsColumnName,
              CanUserSort = true,
              SortMemberPath = columnName,
              ClipboardContentBinding = binding,
              CellTemplate = dataGridTemplateColumnForText.CellTemplate,
              CellEditingTemplate = dataGridTemplateColumnForText.CellEditingTemplate,
              Width = gridColWidth,
              IsReadOnly = isReadOnly,
              Visibility = columnHeadersInfo.colHeaderConfigInfoColl[i].columnVisibility ? Visibility.Visible : Visibility.Hidden

           });


        }
 else if(columnType == "checkBox")
  {
     var CheckboxCol = new DataGridCheckBoxColumn
      {
          Header = columnHeader,
          Width = gridColWidth,
          IsReadOnly = isReadOnly,
          Binding = binding,
          ClipboardContentBinding = binding,
          CanUserSort = true,
          SortMemberPath = columnHeader,
          ElementStyle = this.Resources["CheckBoxStyle"] as Style,
          EditingElementStyle = this.Resources["CheckBoxEditingStyle"] as Style
      };

      this.DataGrid.Columns.Add(CheckboxCol);

}

所以对于这种类型的列创建,我不确定如何使用您建议的示例代码。

您可以使用转换器 class 来实现这一点。 使用转换器并绑定计数属性,如果计数大于2则使用转换器,您可以return bool然后您可以实现对网格的启用和禁用操作。

使用网格强制禁用行为。如果 MaxAddToLabelReached 属性 为假,列将被禁用,反之亦然。

确保,您要么使用转换器,要么使 MaxAddToLabelReached 属性 执行下面的 w.r.t 代码。

在我的一个代码中,这种方法没有问题。

<DataGridTemplateColumn Header="DisplayName" >
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Grid IsEnabled="{Binding MaxAddToLabelReached}">
                <TextBox x:Name="DisplayName" Text="{Binding DisplayName}" />
            </Grid>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

禁用基于 CheckBox 选中状态的列:

XAML :

  <DataGridTemplateColumn>
       <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
               <CheckBox Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"/>
             </DataTemplate>
       </DataGridTemplateColumn.CellTemplate>
   </DataGridTemplateColumn>

代码:

private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            /* apply your own condition here */

            Dgrd.Columns[0].IsReadOnly = true; // disable the entire column of all rows

            // to disable only the corresponding cell of the desired column
            CheckBox chk = (CheckBox)sender;
            DataGridRow row = (DataGridRow)Dgrd.ItemContainerGenerator.ContainerFromItem(chk.DataContext);
            DataGridCell p = (DataGridCell) ((TextBlock)Dgrd.Columns[0].GetCellContent(row)).Parent;
            p.IsEnabled = false;
        }

        private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            /* apply your own condition here */

            // exact opposite of Checked event handler

            Dgrd.Columns[0].IsReadOnly = false; 

            CheckBox chk = (CheckBox)sender;
            DataGridRow row = (DataGridRow)Dgrd.ItemContainerGenerator.ContainerFromItem(chk.DataContext);
            DataGridCell p = (DataGridCell)((TextBlock)Dgrd.Columns[0].GetCellContent(row)).Parent;
            p.IsEnabled = true;
        }