[英]Binding to an ObservableCollection to show the first X number of items c# WPF
好的,所以我現在將ContextMenu
ItemsSource
綁定到ObservableCollection
,比如TypeA
以下代碼位於單例類DataStore中
private ObservableCollection<TypeA> TypeACollection = new ObservableCollection<TypeA>();
public ObservableCollection<TypeA> GetTypeACollection
{
get { return TypeACollection; }
}
public ObservableCollection<TypeA> GetFirstFiveTypeACollection
{
get
{
return TypeACollection.Take(5);
}
}
現在我已經使用以下XAML代碼成功地將ItemsControl
綁定到GetTypeACollection
:
以下代碼位於MainWindow.xaml中
<ItemsControl x:Name="TypeAList" ItemsSource="{Binding GetTypeACollection, Source={StaticResource DataStore}, UpdateSourceTrigger=PropertyChanged}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<User_Controls:TypeAUserControl Type="{Binding }"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
這按預期工作,顯示TypeAUserControl
,使用TypeA
的數據按預期正確格式化
現在,當我嘗試通過將ItemsSource
綁定到GetFirstFiveTypeACollection
在ContextMenu
MenuItem
上重復此操作時,我最初會看到預期的結果,但是在刪除TypeA
對象時,MainWindow ItemsControl
會更新,而ContextMenu
則不會。
我相信這是因為綁定本身位於ContextMenu
和' ObservableCollection<TypeA>
(如GetFirstFiveTypeAColletion
)。
我也通過使用IValueConverter
嘗試了這一點
以下代碼在ValueConverters類中
public class ObservableCollectionTypeAResizeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
ObservableCollection<TypeA> TypeACollection = value as ObservableCollection<TypeA>;
return TypeACollection.Take(System.Convert.ToInt32(parameter));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
}
使用IValueConverter
<MenuItem Header="First 5 Type A" Name="MI_FirstFiveTypeA"
ItemsSource="{Binding DATA_STORE.GetTypeACollection, ConverterParameter=5,
Converter={StaticResource ObservableCollectionTypeAResizeConverter},
Source={StaticResource DataStore}}"
/>
使用GetFirstFiveTypeACollection
<MenuItem Header="First 5 Type A" Name="MI_FirstFiveTypeA"
ItemsSource="{Binding DATA_STORE.RecentTimers, Source={StaticResource DataStore},
UpdateSourceTrigger=PropertyChanged}"
/>
我不知道下一步該怎么做,或者我應該怎么做,任何幫助都將不勝感激!
好的,所以我改變了以下內容
DataStore.cs
private ObservableCollection<TimerType> TimerTypes = new ObservableCollection<TimerType>();
public ObservableCollection<TimerType> getTimerTypes
{
get
{
return new ObservableCollection<TimerType>(TimerTypes.OrderByDescending(t => t.LastUsed));
}
}
public ObservableCollection<TimerType> RecentTimers
{
get
{
return new ObservableCollection<TimerType>(TimerTypes.OrderByDescending(t => t.LastUsed).Take(5));
}
}
public event PropertyChangedEventHandler PropertyChanged;
// Create the OnPropertyChanged method to raise the event
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
//THIS IS IN THE ADD METHOD
TimerTypes.Add(timer);
NotifyPropertyChanged("getTimerTypes");
NotifyPropertyChanged("RecentTimers");
NotifyPropertyChanged("TimerTypes");
//THIS IS IN THE REMOVE METHOD
TimerTypes.Remove(Timer);
NotifyPropertyChanged("getTimerTypes");
NotifyPropertyChanged("RecentTimers");
NotifyPropertyChanged("TimerTypes");
MainWindow.xaml
<ItemsControl x:Name="TimersList" ItemsSource="{Binding Path=getTimerTypes, UpdateSourceTrigger=PropertyChanged}" >
MainWindow.xaml.cs
//Lists are populated in DataStore.cs before this.
DataContext = DataStore.DATA_STORE;
InitializeComponent();
NotifyIcon.xaml
<MenuItem Header="Recent Timers" Name="MIRecent" ItemsSource="{Binding RecentTimers, UpdateSourceTrigger=PropertyChanged}"/>
NotifyIcon.xaml.cs
DataContext = DataStore.DATA_STORE;
InitializeComponent();
所以一切都在開始時正確綁定,但是當刪除TimerType
時, PropertyChangedEventHandler
始終為NULL。 我認為這是一個DataContext
問題,但我很確定我現在有DataContext
和所有Bindings
正確嗎?
private static readonly DataStore Instance = new DataStore();
private DataStore() { }
public static DataStore DATA_STORE
{
get { return Instance; }
set { }
}
不幸的是,通過使用Take
(或任何LINQ方法),您可以獲得直接的IEnumerable
。 當您綁定它時,沒有INotifyCollectionChanged
因此對集合的更改不會導致UI更新。
由於缺少INotifyCollectionChanged
,因此沒有真正的解決方法。 最好的辦法是在添加/刪除項目以強制UI重新計算IEnumerable
時,針對“子集”屬性引發PropertyChanged
。
您可以使用CollectionView解決此問題
public class MyViewModel
{
CollectionView _mostRecentDocuments;
public MyViewModel()
{
Documents = new ObservableCollection<Document>();
_mostRecentDocuments = new CollectionView(Documents);
_mostRecentDocuments .Filter = x => Documents.Take(5).Contains(x);
}
public ObservableCollection<Document> Documents { get; private set; }
public CollectionView MostRecentDocuments
{
get
{
return _mostRecentDocuments;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.