WPF DataGrid中根据绑定属性值隐藏对应行的CheckBox
问题描述
我通过Binding填充WPF DataGrid,每行都显示一个CheckBox。希望在不隐藏整行的前提下,当CheckBox绑定的Selected属性值为false时隐藏该CheckBox,请问这是否可行?
我定义的绑定类如下:
public class DataSet { public string XDim { get; set; } public string YDim { get; set; } public bool Selected { get; set; } }
DataGrid的XAML定义:
<DataGrid> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Path=XDim }" Width="65" Header="X Dimension" IsReadOnly="True"/> <DataGridTextColumn Binding="{Binding Path=YDim}" Width="85" Header="Y Dimension" IsReadOnly="True"/> <DataGridTemplateColumn Header="Selected" ClipboardContentBinding="{Binding Selected}"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ToggleButton Margin="0" IsChecked="{Binding Selected, UpdateSourceTrigger=PropertyChanged}"> <ToggleButton.Template> <ControlTemplate TargetType="ToggleButton"> <Grid Background="Transparent"> <ContentPresenter /> </Grid> </ControlTemplate> </ToggleButton.Template> <CheckBox Margin="20,3,0,0" IsChecked="{Binding IsChecked, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=ToggleButton}}"/> </ToggleButton> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> </DataGrid.Columns> </DataGrid>
我尝试添加了布尔属性visibility(public bool visibility{ get; set;}),并创建了如下Style应用到CheckBox,但没有效果,请问我遗漏了什么?
<Style x:Key="cBVisibility" TargetType="CheckBox"> <Style.Triggers> <DataTrigger Binding="{Binding ElementName=visibility,Path=Text}" Value="false"> <Setter Property="Visibility" Value="Hidden"/> </DataTrigger> </Style.Triggers> </Style> <DataGridTemplateColumn Header="Selected" ClipboardContentBinding="{Binding Selected}"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <ToggleButton Margin="0" IsChecked="{Binding Selected, UpdateSourceTrigger=PropertyChanged}"> <ToggleButton.Template> <ControlTemplate TargetType="ToggleButton"> <Grid Background="Transparent"> <ContentPresenter /> </Grid> </ControlTemplate> </ToggleButton.Template> <CheckBox Style="{StaticResource cBVisibility}" Margin="20,3,0,0" IsChecked="{Binding IsChecked, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=ToggleButton}}" Visibility="{Binding visibility}" /> </ToggleButton> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn>
解决方案
完全可行,你的问题出在绑定逻辑和属性使用的错误上,修正后就能实现需求:
核心问题分析
- 你额外添加的
visibility属性完全冗余,直接用现有的Selected属性就能控制CheckBox显示/隐藏 - DataTrigger绑定错误:
ElementName=visibility是错误的写法,visibility是DataSet类的属性,不是UI元素,直接绑定{Binding Selected}即可;同时布尔值不需要加引号,Value=false而非Value="false" - Visibility是枚举类型,不能直接绑定布尔值,需要用DataTrigger或转换器处理
实现方式一:使用DataTrigger(无需额外转换器)
修改CheckBox的Style,直接通过Selected属性控制Visibility:
<Style x:Key="cBVisibility" TargetType="CheckBox"> <Style.Triggers> <!-- 当Selected为false时隐藏CheckBox --> <DataTrigger Binding="{Binding Selected}" Value="False"> <Setter Property="Visibility" Value="Hidden"/> </DataTrigger> <!-- Selected为true时默认显示,此触发器可省略 --> <DataTrigger Binding="{Binding Selected}" Value="True"> <Setter Property="Visibility" Value="Visible"/> </DataTrigger> </Style.Triggers> </Style>
然后在CheckBox上应用该Style,移除冗余的Visibility绑定:
<CheckBox Style="{StaticResource cBVisibility}" Margin="20,3,0,0" IsChecked="{Binding IsChecked, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=ToggleButton}}"/>
实现方式二:使用BooleanToVisibilityConverter(更简洁)
首先在窗口资源中声明内置转换器:
<Window.Resources> <BooleanToVisibilityConverter x:Key="BoolToVis"/> </Window.Resources>
然后直接绑定CheckBox的Visibility到Selected属性,通过ConverterParameter=Invert反转逻辑(因为需要Selected=false时隐藏):
<CheckBox Margin="20,3,0,0" IsChecked="{Binding IsChecked, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=ToggleButton}}" Visibility="{Binding Selected, Converter={StaticResource BoolToVis}, ConverterParameter=Invert}"/>
可选简化:移除嵌套的ToggleButton
如果没有特殊交互需求,完全可以去掉ToggleButton,直接在CellTemplate中放CheckBox,代码更简洁:
<DataGridTemplateColumn Header="Selected" ClipboardContentBinding="{Binding Selected}"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <CheckBox Margin="20,3,0,0" IsChecked="{Binding Selected, UpdateSourceTrigger=PropertyChanged}" Visibility="{Binding Selected, Converter={StaticResource BoolToVis}, ConverterParameter=Invert}"/> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn>
内容的提问来源于stack exchange,提问作者user21124346
相关产品推荐
相关产品推荐

