2015-02-10 52 views
0

我試圖修改一個網格的屬性,取決於ObservableCollection<>ItemsSource是否有任何項目被綁定。我目前在網格上有一個OnItemsSourceChanged事件,但問題是ItemsSource是一個對象,如果沒有投射它,我無法訪問ObservableCollection<>CollectionChanged事件。 ObservableCollection<>的通用類型在運行時才能確定,並且可能是很多事情。如何獲取作爲ObservableCollection <>的ItemsSource?

我試過用ItemsSource as ObservableCollection<object>來鑄造它,但是它返回null。 ItemsSource as ObservableCollection<dynamic>也沒有運氣。做ItemsSource as IEnumerable<object>足夠令人驚訝,但仍然不允許我訪問CollectionChanged事件。

如何將我的對象投射到底層ObservableCollection<>?我寧願避免使用反射,但我不會在這裏挑剔。

+0

你想修改哪些網格屬性? – 2015-02-10 21:15:36

回答

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(); 
    } 
} 

OR甚至可能更好

<Grid Name="MyGrid" ItemsSource="{Binding MyObservableCollection" /> 

<TextBlock Visibility="{Binding HasItems, ElementName=MyGrid, Converter={StaticResource BoolToVisibilityConverter}}" /> 

最後手段以供將來參考

你的最後一招會的比較好,露出一個屬性shouldBe這樣/ ISVISIBLE在你的ViewModel和並綁定到您的視圖。

+0

那麼,那只是完全滑過我的頭。該演員確實有效。我已經解釋了我的動機,但是無論如何,這是因爲我想根據是否在我的ItemsSource中有項目來更改網格的屬性,這些項目綁定到在ViewModel中定義的ObservableCollection <>。我不知道有一個更好的方法來做這個檢查,但如果你知道一個,我會感興趣。 – Lunyx 2015-02-10 21:15:28

+0

請參閱編輯的一些想法 – 2015-02-10 21:41:31

+0

我正在做一個擴展(自定義)數據網格控件中的此功能以及許多其他功能,以便它可以重複使用。我無法找到一種方法來綁定到xaml的項目數量,我不確定綁定到ItemsSource並使用轉換器會觸發由ObservableCollection更改和ItemsSource更改引發的更改。 – Lunyx 2015-02-10 22:30:12

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>泛型類型來處理該事件。

+0

這就是我最終要做的事,但其他人先回答了。然而,我仍然好奇爲什麼將它轉換爲IEnumerable 作品。 – Lunyx 2015-02-10 21:20:00

+0

很抱歉,如果我建議在IEnumerable 的某個位置投射,我已經更加明確地使用ICollection來避免消費者代碼需要了解包含的類型(例如)。雖然,我相信這是因爲IEnumerable 上的協變/逆變規則,請參閱:http://stackoverflow.com/questions/6508529/c-sharp-covariant-generic-parameter – 2015-02-10 21:23:37

+0

@Lunyx我認爲'IEnumerable '是協變的,而'ObservableCollection '不是。這意味着您可以將其轉換爲更通用的版本。實現可修改集合的協方差時會遇到一些後勤問題,因此不受支持。 – HugoRune 2015-02-10 21:28:35

相關問題