gpt4 book ai didi

c# - 绑定(bind)到 ObservableCollection 以显示前 X 个项目 c# WPF

转载 作者:太空狗 更新时间:2023-10-29 23:30:04 25 4
gpt4 key购买 nike

背景说明

好的,我目前正在绑定(bind) ContextMenu ItemsSourceObservableCollection可以说 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);
}
}

现在我已经成功绑定(bind)了一个ItemsControlGetTypeACollection使用以下 XAML 代码:

以下代码在 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 中的数据按预期正确格式化

现在,当我尝试在 ContextMenu 上重复此操作时MenuItem通过绑定(bind) ItemsSourceGetFirstFiveTypeACollection我最初看到了预期的结果,但是在删除 TypeA 时对象 MainWindow ItemsControlContextMenu 的位置更新不是。

我认为这是因为绑定(bind)本身位于 ContextMenu 之间。和一个"new"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;
}
}

我试过的XAML代码。

使用 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();

所以一切都在开始时正确绑定(bind),但是当 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。当您绑定(bind)到它时,没有 INotifyCollectionChanged,因此对集合的更改不会导致 UI 更新。

由于缺少 INotifyCollectionChanged,因此没有真正的解决方法。您最好的选择是在添加/删除项目时针对您的“子集”属性引发 PropertyChanged 以强制 UI 重新枚举 IEnumerable

关于c# - 绑定(bind)到 ObservableCollection 以显示前 X 个项目 c# WPF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33263652/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com