如何在WPF ListView中启用/禁用单个列表项?
问题根因
你在DataTemplate内部给Grid、TextBlock设置IsEnabled不生效,核心原因是:
每个ListView的数据项都会被外层的ListViewItem容器包裹,WPF的属性继承机制会让容器的IsEnabled属性优先级高于内部子元素设置的同名属性,只要ListViewItem本身的IsEnabled保持默认True,你无论怎么修改内部子元素的IsEnabled,都会被父容器的属性值覆盖,自然不会生效。
修复方案
不要在CellTemplate的内部元素上绑定IsEnabled,直接通过ItemContainerStyle修改ListViewItem容器本身的IsEnabled属性即可,修改后的完整代码如下:
<ListView SelectionMode="Single" Width="auto" Margin="0 20" SelectedItem="{Binding SelectedMiningModule}" ItemsSource="{Binding MiningModules}" MouseDoubleClick="AssignMiningModule_MouseDoubleClick"> <!-- 直接控制列表项容器的启用状态,内部元素会自动继承该状态 --> <ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Setter Property="IsEnabled" Value="{Binding IsSelected}"/> </Style> </ListView.ItemContainerStyle> <ListView.View> <GridView> <GridViewColumn Header="Module"> <GridViewColumn.CellTemplate> <DataTemplate> <Grid> <TextBlock Text="{Binding DisplayName}" /> </Grid> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView> </ListView.View> </ListView>
- 实现效果:绑定生效后,
IsSelected属性为False的数据项会整体变灰禁用,IsSelected为True的项保持可交互状态 - 注意事项:不需要再给Grid、TextBlock等内部子元素重复设置
IsEnabled绑定,父容器的状态会自动沿可视化树向下传递给所有子元素
你之前直接给内部元素硬编码
IsEnabled="False"仍然无效,就是父容器属性优先级覆盖子元素设置的典型表现,和绑定逻辑本身没有关系。
内容的提问来源于stack exchange,提问作者aberforth
相关产品推荐
相关产品推荐

