// Cascader.cs using System.Collections; using System.Globalization; using System.Windows.Data; namespace Melskin.Converters.Internal; /// /// HasChildrenMultiConverter 类实现 IMultiValueConverter 接口,用于在 WPF 应用程序中检查数据项是否包含子项。 /// 该转换器通常应用于级联菜单或需要根据数据项是否有子项来决定显示行为的控件。通过提供一个静态实例(Instance), /// 可以方便地在 XAML 中作为资源引用,从而简化绑定配置过程。此转换器接受两个输入值:一个是待检查的数据项, /// 另一个是表示子项集合属性名称的字符串。如果指定的属性存在且其值为非空可枚举类型,则返回 true,表明该数据项有子项; /// 否则返回 false。 /// internal class HasChildrenMultiConverter : IMultiValueConverter { /// /// HasChildrenMultiConverter 的单例实例,用于在 XAML 中通过静态资源引用。 /// 该实例提供了一个方便的方式来检查数据项是否包含子项,通常用于级联菜单或其他需要展开子项的控件中。 /// public static readonly HasChildrenMultiConverter Instance = new(); /// public object Convert(object[]? values, Type targetType, object parameter, CultureInfo culture) { // IMultiValueConverter 的输入是一个对象数组 (values) // 根据我们在 XAML 中定义的 MultiBinding,我们期望: // values[0] 是当前的数据项 (例如 Staff 对象) // values[1] 是 SubmenuMemberPath 属性的值 (例如 "StaffList" 字符串) if (values == null || values.Length < 2 || values[0] == null || values[1] == null) { return false; } var dataItem = values[0]; var childPropertyName = values[1].ToString(); if (string.IsNullOrEmpty(childPropertyName)) { return false; } // 后续逻辑与之前完全相同:使用反射来检查子集合 var propertyInfo = dataItem.GetType().GetProperty(childPropertyName); if (propertyInfo == null) { return false; } var children = propertyInfo.GetValue(dataItem) as IEnumerable; return children != null && children.Cast().Any(); } /// public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }