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;
}
我用 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;
}