如何获取 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> 的通用类型。