如何获取 ItemsSource 作为 ObservableCollection<>?
How can I get an ItemsSource as an ObservableCollection<>?
我正在尝试根据 ObservableCollection<>
中是否有 ItemsSource
绑定到的任何项目来修改网格的 属性。我目前在网格上有一个 OnItemsSourceChanged
的事件,但问题是 ItemsSource
是一个对象,如果不转换它,我无法访问 CollectionChanged
的事件ObservableCollection<>
。 ObservableCollection<>
的泛型直到运行时才确定,可以是很多东西。
我试过用 ItemsSource as ObservableCollection<object>
转换它,但是 returns 为空。 ItemsSource as ObservableCollection<dynamic>
也不走运。执行 ItemsSource as IEnumerable<object>
的效果令人惊讶,但仍然不允许我访问 CollectionChanged
事件。
如何将我的对象转换为基础 ObservableCollection<>
?我宁愿避免使用反射,但我不会在这里挑剔。
如何将其转换为 INotifyCollectionChanged?
编辑:
你可能应该做的是这样的:
<TextBlock Visibility="{Binding MyObservableCollection.Count, Converter={StaticResource NonZeroToVisibleConverter}}">
其中 NonZeroToVisibleConverter
类似于:
public class ColorConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
return (int)value > 0 ? Visibility.Visible : Visibility.Collapsed
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplmentedException();
}
}
或 可能更好
<Grid Name="MyGrid" ItemsSource="{Binding MyObservableCollection" />
<TextBlock Visibility="{Binding HasItems, ElementName=MyGrid, Converter={StaticResource BoolToVisibilityConverter}}" />
不得已 供日后参考
你的最后一招最好是在你的 ViewModel 中公开一个 属性 ShouldBe/IsVisible 并绑定到你的视图中。
考虑以下代码:
// where
ObservableCollection<Foo> foo = new();
element.ItemsSource = foo;
// then negotiate to non-generic types
var bar = element.ItemsSource as INotifyCollectionChanged;
bar.CollectionChanged += (NotifyCollectionChangedEventHandler)(delegate(object sender, NotifyCollectionChangedEventArgs e)
{
var collection = bar as ICollection;
// TODO: handle based on collection.Count
});
这样您就可以处理事件,而不管应用于 ObservableCollection<T>
的通用类型。
我正在尝试根据 ObservableCollection<>
中是否有 ItemsSource
绑定到的任何项目来修改网格的 属性。我目前在网格上有一个 OnItemsSourceChanged
的事件,但问题是 ItemsSource
是一个对象,如果不转换它,我无法访问 CollectionChanged
的事件ObservableCollection<>
。 ObservableCollection<>
的泛型直到运行时才确定,可以是很多东西。
我试过用 ItemsSource as ObservableCollection<object>
转换它,但是 returns 为空。 ItemsSource as ObservableCollection<dynamic>
也不走运。执行 ItemsSource as IEnumerable<object>
的效果令人惊讶,但仍然不允许我访问 CollectionChanged
事件。
如何将我的对象转换为基础 ObservableCollection<>
?我宁愿避免使用反射,但我不会在这里挑剔。
如何将其转换为 INotifyCollectionChanged?
编辑:
你可能应该做的是这样的:
<TextBlock Visibility="{Binding MyObservableCollection.Count, Converter={StaticResource NonZeroToVisibleConverter}}">
其中 NonZeroToVisibleConverter
类似于:
public class ColorConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
return (int)value > 0 ? Visibility.Visible : Visibility.Collapsed
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplmentedException();
}
}
或 可能更好
<Grid Name="MyGrid" ItemsSource="{Binding MyObservableCollection" />
<TextBlock Visibility="{Binding HasItems, ElementName=MyGrid, Converter={StaticResource BoolToVisibilityConverter}}" />
不得已 供日后参考
你的最后一招最好是在你的 ViewModel 中公开一个 属性 ShouldBe/IsVisible 并绑定到你的视图中。
考虑以下代码:
// where
ObservableCollection<Foo> foo = new();
element.ItemsSource = foo;
// then negotiate to non-generic types
var bar = element.ItemsSource as INotifyCollectionChanged;
bar.CollectionChanged += (NotifyCollectionChangedEventHandler)(delegate(object sender, NotifyCollectionChangedEventArgs e)
{
var collection = bar as ICollection;
// TODO: handle based on collection.Count
});
这样您就可以处理事件,而不管应用于 ObservableCollection<T>
的通用类型。