绑定到一列数据网格并应用样式
Bind to one column of datagrid and apply style
我有一个使用 MVVM 绑定到数据表的 WPF 数据网格。此数据表中有几列,其中一列是可为空的布尔值。呈现数据网格时,布尔列(主要包含空值)显示 block-filled 复选框并且看起来很糟糕:
当前: Desired:
我想为此列添加一种样式,以便在值为 null 时隐藏所有复选框。
这个问题类似于 apply a template to a column of datagrid,但是我无法手动定义 XAML 中的每一列,因为绑定数据表中列的数量和位置可能会发生变化。
我的数据表在视图模型中定义为:
public DataTable Data
{
get { return data; }
set
{
data = value;
OnPropertyChanged("Data");
}
}
并通过调用 returns 数据表的 SQL 存储过程在 class 构造函数中设置。此存储过程可能因使用情况而异,因此会在不同时间生成不同的数据表。
目前,我有这个代码:
<DataGrid ItemsSource="{Binding Data, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True">
<DataGrid.Columns>
<DataGridCheckBoxColumn Binding="{Binding Paid}" Header="Paid?">
<DataGridCheckBoxColumn.ElementStyle>
<Style TargetType="CheckBox">
<Style.Triggers>
<Trigger Property="IsChecked" Value="{x:Null}">
<Setter Property="Visibility" Value="Hidden"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGridCheckBoxColumn.ElementStyle>
</DataGridCheckBoxColumn>
</DataGrid.Columns>
</DataGrid>
但是,添加此代码已将我的数据网格列从:
并且只是在网格的开头添加了一个新的复选框列:
新添加的列确实显示了所需的复选框效果(仅显示了具有值的复选框)但是原始的 'Paid' 列未受影响。
有人可以告诉我如何将我的样式仅绑定到这一列吗?
您当前将 AutoGenerateColumns
设置为 true,这意味着 DataGrid
将首先使用您的自定义列定义,然后将其自己的定义附加到 DataGrid
,这就是您得到的原因第一个 "Paid?" 列,然后是自动生成的其余列。
要获得您想要的布局,您可以将 AutoGenerateColumns
设置为 false
并提供所有列的定义。
否则,尝试将本地资源分配给 DataGrid
以使用您的自定义 ElementStyle
设置所有 DataGridCheckBoxColumns
的样式。另请注意,您也可以简单地将列上的 IsThreeState
属性 设置为 false
,这应该会停止出现 {x:Null}
状态。
更新:
更深入地研究一下,将 AutoGenerateColumns
设置为 true
的 DataGridCheckBoxColumn
样式可能存在问题。您将需要处理 AutoGeneratingColumn
事件并在处理程序中设置 ElementStyle
。
类似于:
void grid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if(e.Column is DataGridCheckBoxColumn)
{
var checkBoxColumn = e.Column as DataGridCheckBoxColumn;
var resource = Application.Current.FindResource(typeof(CheckBox));
checkBoxColumn.ElementStyle = resource as Style;
}
}
我有一个使用 MVVM 绑定到数据表的 WPF 数据网格。此数据表中有几列,其中一列是可为空的布尔值。呈现数据网格时,布尔列(主要包含空值)显示 block-filled 复选框并且看起来很糟糕:
当前:
我想为此列添加一种样式,以便在值为 null 时隐藏所有复选框。 这个问题类似于 apply a template to a column of datagrid,但是我无法手动定义 XAML 中的每一列,因为绑定数据表中列的数量和位置可能会发生变化。
我的数据表在视图模型中定义为:
public DataTable Data
{
get { return data; }
set
{
data = value;
OnPropertyChanged("Data");
}
}
并通过调用 returns 数据表的 SQL 存储过程在 class 构造函数中设置。此存储过程可能因使用情况而异,因此会在不同时间生成不同的数据表。
目前,我有这个代码:
<DataGrid ItemsSource="{Binding Data, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True">
<DataGrid.Columns>
<DataGridCheckBoxColumn Binding="{Binding Paid}" Header="Paid?">
<DataGridCheckBoxColumn.ElementStyle>
<Style TargetType="CheckBox">
<Style.Triggers>
<Trigger Property="IsChecked" Value="{x:Null}">
<Setter Property="Visibility" Value="Hidden"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGridCheckBoxColumn.ElementStyle>
</DataGridCheckBoxColumn>
</DataGrid.Columns>
</DataGrid>
但是,添加此代码已将我的数据网格列从:
并且只是在网格的开头添加了一个新的复选框列:
新添加的列确实显示了所需的复选框效果(仅显示了具有值的复选框)但是原始的 'Paid' 列未受影响。
有人可以告诉我如何将我的样式仅绑定到这一列吗?
您当前将 AutoGenerateColumns
设置为 true,这意味着 DataGrid
将首先使用您的自定义列定义,然后将其自己的定义附加到 DataGrid
,这就是您得到的原因第一个 "Paid?" 列,然后是自动生成的其余列。
要获得您想要的布局,您可以将 AutoGenerateColumns
设置为 false
并提供所有列的定义。
否则,尝试将本地资源分配给 DataGrid
以使用您的自定义 ElementStyle
设置所有 DataGridCheckBoxColumns
的样式。另请注意,您也可以简单地将列上的 IsThreeState
属性 设置为 false
,这应该会停止出现 {x:Null}
状态。
更新:
更深入地研究一下,将 AutoGenerateColumns
设置为 true
的 DataGridCheckBoxColumn
样式可能存在问题。您将需要处理 AutoGeneratingColumn
事件并在处理程序中设置 ElementStyle
。
类似于:
void grid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
if(e.Column is DataGridCheckBoxColumn)
{
var checkBoxColumn = e.Column as DataGridCheckBoxColumn;
var resource = Application.Current.FindResource(typeof(CheckBox));
checkBoxColumn.ElementStyle = resource as Style;
}
}