C# 如何将ObservableCollection的前N项绑定到ItemsControl?
我想将ObservableCollection的前N个项绑定到ItemsControl 我尝试过这个解决方案: 这是我的代码:C# 如何将ObservableCollection的前N项绑定到ItemsControl?,c#,wpf,observablecollection,C#,Wpf,Observablecollection,我想将ObservableCollection的前N个项绑定到ItemsControl 我尝试过这个解决方案: 这是我的代码: XAML: 代码隐藏: using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Linq;
XAML:
代码隐藏:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
IC.ItemsSource = CM.TopCollection;
}
CollectionModel CM = new CollectionModel();
public class TestModel {
public string ABC { get; set; }
}
public class CollectionModel : ObservableCollection<TestModel>, INotifyPropertyChanged
{
public CollectionModel()
{
CollectionChanged += MyCollection_CollectionChanged;
}
private void MyCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{ // to notify XAML-side binding
OnPropertyChanged(new PropertyChangedEventArgs(nameof(TopCollection)));
}
public IEnumerable<TestModel> TopCollection => this.Take(10);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
CM.Add(new TestModel() {ABC= Guid.NewGuid().ToString() });
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用System.Collections.Specialized;
使用系统组件模型;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Documents;
使用System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
命名空间WpfApp1
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
IC.ItemsSource=CM.TopCollection;
}
CollectionModel CM=新的CollectionModel();
公共类测试模型{
公共字符串ABC{get;set;}
}
公共类集合模型:ObservableCollection,INotifyPropertyChanged
{
公共集合模型()
{
CollectionChanged+=MyCollection\u CollectionChanged;
}
私有void MyCollection\u CollectionChanged(对象发送方,NotifyCollectionChangedEventArgs e)
{//通知XAML端绑定
OnPropertyChanged(新PropertyChangedEventArgs(名称)(TopCollection));
}
public IEnumerable TopCollection=>this.Take(10);
}
私有无效按钮\u单击(对象发送者,路由目标e)
{
Add(newtestmodel(){ABC=Guid.NewGuid().ToString()});
}
}
}
我按了一下按钮。但是,CM
成功添加了新项目,但用户界面没有更新任何项目
为什么结果是这样
我使用断点进行测试,发现CollectionChanged
&OnPropertyChanged
都工作正常。但是为什么UI仍然没有更新?你能帮帮我吗?谢谢。您需要绑定到
CollectionModel
的TopCollection
属性,才能使PropertyChanged
事件生效:
public MainWindow()
{
InitializeComponent();
DataContext = CM;
IC.SetBinding(ItemsControl.ItemsSourceProperty, new Binding("TopCollection"));
}
如果将DataContext
设置为实现INotifyPropertyChanged
的CollectionModel
,则可以在XAML标记中执行此操作:
<ItemsControl x:Name="IC" ItemsSource="{Binding TopCollection}" ... />
您的收集模型是一个可观察的收集,您做得非常正确。这意味着,当添加/删除项目时,它将引发事件(供订阅者观察和处理) 然而,您实际绑定到的“TopCollection”只是一个IEnumerable。简而言之,它不会引发使其完全数据绑定的事件
您需要公开TopCollection的ObservableCollection。然后,您可以在其基础数据源更改时,甚至仅在其筛选结果更改时引发事件。现在,您只需设置ItemsSource一次。但您需要在更新实际的支持数据后进行更新。通常,这是通过
绑定来完成的(您在上面的代码中也部分使用了绑定)。。。理论上可以由一些附加属性或CollectionViewSource处理,但是,即使我替换了“public IEnumerable TopCollection=>this.Take(10);”到“PublicObservableCollection TopCollection=>NewObservableCollection(this.Take(10));”。还是不行。是的,@mm8的改变也是必要的。尽管如此,还是要谢谢你。我已经努力了,并且成功了。然而,我需要将窗口的DataContext绑定到窗口本身,因此无法将其绑定到模型。有没有其他方法可以实现这一点?使CM成为窗口的公共属性,并将ItemsSource
绑定到“CM.TopCollection”。也许我发现了我的问题,我应该将CM绑定到ItemsSource,但不将其设置为ItemsSource。是的,我更改了如下代码:IC.SetBinding(ItemsControl.ItemsSourceProperty,新绑定{Source=CM}); 它成功了。
<ItemsControl x:Name="IC" ItemsSource="{Binding TopCollection}" ... />