如何将ItemsSource作为ObservableCollection<>?

时间:2015-02-10 21:06:58

标签: c# wpf generics casting

我正在尝试修改网格的属性,具体取决于ObservableCollection<>绑定的ItemsSource中是否有任何项目。我目前在网格上有一个OnItemsSourceChanged的事件,但问题是ItemsSource是一个对象,如果没有强制转换它,我就无法访问CollectionChanged事件ObservableCollection<>ObservableCollection<>的泛型类型在运行时之前是未确定的,可以是很多东西。

我尝试使用ItemsSource as ObservableCollection<object>进行投射,但返回null。也没有运气ItemsSource as ObservableCollection<dynamic>。执行ItemsSource as IEnumerable<object>的效果令人惊讶,但仍然无法访问CollectionChanged事件。

如何将我的对象转换为基础ObservableCollection<>?我宁愿避免使用反射,但我不会在这里挑剔。

2 个答案:

答案 0 :(得分:1)

如何将其投射到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,然后绑定到View中的属性。

答案 1 :(得分:1)

请考虑以下代码:

// 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>的通用类型如何,您都能够处理该事件。