禁用特定数据网格单元与绑定
本文关键字:网格 单元 绑定 数据网 数据 | 更新日期: 2023-09-27 18:09:45
我正在尝试将自定义数据对象列表绑定到数据网格并实现以下行为。
- 填充网格
- 基于对象数据禁用某些单元格。
考虑以下DataGrid
<DataGrid ItemsSource="{Binding Path=CustomObjectList}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=FieldName}"
Header="Field Name"
IsReadOnly="True" />
<DataGridCheckBoxColumn Binding="{Binding Path=Compare}"
Header="Compare" />
<DataGridTextColumn Binding="{Binding Path=Tolerance}"
Header="Tolerance" />
</DataGrid.Columns>
</DataGrid>
有了这样一个支持对象…
public class CustomObject: BaseModel
{
private bool _compare;
private bool _disableTolerance;
private string _fieldName;
private bool _mustCompare;
private double _tolerance;
/// <summary>
/// Gets or sets the compare.
/// </summary>
/// <value>The compare.</value>
public bool Compare
{
get
{
return this._compare;
}
set
{
this._compare = value;
this.NotifyPropertyChange("Compare");
}
}
/// <summary>
/// Gets or sets the disable tolerance.
/// </summary>
/// <value>The disable tolerance.</value>
public bool DisableTolerance
{
get
{
return this._disableTolerance;
}
set
{
this._disableTolerance = value;
this.NotifyPropertyChange("DisableTolerance");
}
}
/// <summary>
/// Gets or sets the name of the field.
/// </summary>
/// <value>The name of the field.</value>
public string FieldName
{
get
{
return this._fieldName;
}
set
{
this._fieldName = value;
this.NotifyPropertyChange("FieldName");
}
}
/// <summary>
/// Gets or sets the must compare.
/// </summary>
/// <value>The must compare.</value>
public bool MustCompare
{
get
{
return this._mustCompare;
}
set
{
this._mustCompare = value;
this.NotifyPropertyChange("MustCompare");
}
}
/// <summary>
/// Gets or sets the tolerance.
/// </summary>
/// <value>The tolerance.</value>
public double Tolerance
{
get
{
return this._tolerance;
}
set
{
this._tolerance = value;
this.NotifyPropertyChange("Tolerance");
}
}
}
您可以考虑这样填充CustomObjectList…
this.ComparisonsAndTolerances.Add(new ComparisonSettingsTolerances()
{
FieldName = "Alpha",
Compare = true,
MustCompare = true,
Tolerance = 0,
DisableTolerance = false
});
this.ComparisonsAndTolerances.Add(new ComparisonSettingsTolerances()
{
FieldName = "Bravo",
Compare = true,
MustCompare = false,
Tolerance = 0,
DisableTolerance = true
});
因此,当然FieldName, Compare,和Tolerance属性被适当地填充到网格中。
然而,我想要实现的是,当MustCompare为true时,该单元格被标记为只读。当disablettolerance为true时,该单元格被标记为只读。
显然,这将因细胞和行与4种不同的组合而异,但我希望通过绑定来实现这一点。
我试着
IsReadOnly="{Binding Path=MustCompare}"
和
IsReadOnly="{Binding Path=CustomObjectList/MustCompare}"
但这两种方法都不起作用。
谢谢。
这是一个有趣的bug/情况。
会发生什么?好吧,绑定试图绑定到MustCompare
属性(并且可能已经成功),但它找不到FrameworkElement
或FrameworkContentElement
作为绑定的目标,因为没有数据网格的列在可视化树中。
有一个解决方案,尽管没有你(正确的)尝试做的那么优雅:
<DataGridTemplateColumn Header="Compare">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock x:Name="TextHolder" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=Compare}"
Value="True">
<Setter TargetName="TextHolder"
Property="Text"
Value="True" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=Compare}"
Value="False">
<Setter TargetName="TextHolder"
Property="Text"
Value="False" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<CheckBox x:Name="Check"
IsChecked="{Binding Path=Compare}"
ToolTipService.ShowOnDisabled="True"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=MustCompare}"
Value="True">
<Setter TargetName="Check"
Property="IsEnabled"
Value="False" />
<Setter TargetName="Check"
Property="ToolTip"
Value="You cannot change this value since this item must compare" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
我已经改变了单元格,所以它在非编辑模式下显示文本,在编辑时显示复选框(只是为了看看单元格处于什么状态,你可以在两种情况下将其更改为复选框)。
这不是最优的,如果你(或任何人)找到一个更好的解决方案,我想听听你的意见。
编辑:
我想到了另一个解决方案:
<DataGridCheckBoxColumn Binding="{Binding Path=Compare}"
Header="Compare">
<DataGridCheckBoxColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<DataTrigger Binding="{Binding MustCompare}"
Value="True">
<Setter Property="IsEnabled"
Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridCheckBoxColumn.CellStyle>
</DataGridCheckBoxColumn>
这会使复选框在非编辑模式下被禁用,因此它看起来不同。这可能是好事,也可能是坏事,这取决于你的功能设计。