如何基于分组内容属性设置WPF ListView中Expander.Header的样式与状态
实现方案
你思路的方向完全可行,CollectionViewGroup的Items属性本身就包含了当前分组的所有条目,直接绑定该属性到转换器即可实现需求,以下是具体实现步骤:
方案1:使用IValueConverter实现(快速适配现有代码)
第一步:实现脏数据判断转换器
新建转换器类:
public class GroupHasDirtyItemConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is not IEnumerable items) { // 无有效条目时返回对应类型默认值 return targetType == typeof(Brush) ? Brushes.Black : false; } // 遍历分组内所有条目判断是否存在IsDirty为true的项 foreach (var item in items.OfType<OverViewModel>()) { if (item.IsDirty) { // 适配Foreground绑定需求返回高亮色 if (targetType == typeof(Brush)) return Brushes.Red; // 适配IsExpanded绑定需求返回true return true; } } // 无脏数据返回默认值 return targetType == typeof(Brush) ? Brushes.Black : false; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
第二步:注册转换器到窗口资源
在你的窗口资源中添加转换器声明:
<local:GroupHasDirtyItemConverter x:Key="GroupHasDirtyConverter"/>
第三步:修改XAML绑定
调整Expander对应属性的绑定逻辑即可:
<Expander IsExpanded="{Binding DataContext.Overviews_IsExpanded,RelativeSource={RelativeSource AncestorType=Window},Mode=OneTime}"> <Expander.Header> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Items[0].TargetOverView.Goods_Name}" <!-- 绑定当前分组所有条目到转换器,自动判断是否有脏数据调整颜色 --> Foreground="{Binding Path=Items, Converter={StaticResource GroupHasDirtyConverter}}"/> </StackPanel> </Expander.Header> <Expander.Content> <ItemsPresenter/> </Expander.Content> </Expander>
如果需要同时调整IsExpanded属性,直接用同样的绑定逻辑替换原有IsExpanded绑定即可,也可以用多绑定合并两个判断逻辑。
方案2:ViewModel侧预计算(推荐,支持动态更新)
如果需要在条目IsDirty修改后实时同步Header状态,推荐在ViewModel层新增分组视图模型,每个分组单独增加HasDirtyItem属性,监听分组内集合变更、条目IsDirty属性变更时自动更新该属性,直接绑定该属性到UI即可,性能和可维护性更好。
内容的提问来源于stack exchange,提问作者High Plains Grifter
相关产品推荐
相关产品推荐

