这是怎么回事。我有一个viewmodel,我调用webclient并用项目填充可观察的集合。我需要在两个不同的页面中有两个不同的列表框,但是viewmodel中有相同的ItemsSource。如何限制两个列表框之一中的项目数而不影响另一个?我尝试使用.Take(limit)进入正在创建项目的viewmodel,但这会影响两个列表框。
更新
viewmodel
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
this.Items = new ObservableCollection<ItemViewModel>();
this.Mainlist = new CollectionViewSource();
}
public ObservableCollection<ItemViewModel> Items { get; private set; }
public CollectionViewSource Mainlist { get; set; }
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
try
{
...............
//Ignore the dummy data in foreach loop. Just for showcase.
foreach (var item in Items)
{
//Items creation
this.Items.Add(new ItemViewModel()
{ LineOne = item });
}
this.Mainlist.Source = App.ViewModel.Items;
this.Mainlist.Filter += (s, a) =>
a.Accepted = App.ViewModel.Items.IndexOf((ItemViewModel)a.Item) < 10;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
.....................
}
在视图一侧
public MainPage()
{
InitializeComponent();
DataContext = App.ViewModel;
list.ItemsSource = App.ViewModel.Mainlist.View;
}
更新2
我找到的另一个选项(不使用CollectionViewSource
)是制作新的public ObservableCollection<ItemViewModel> Mainlist { get; private set; }
并再使用一个
foreach (var item in Items.Take(limit))
{
//Items creation
this.Mainlist.Add(new ItemViewModel()
{ LineOne = item });
}
为了填充ObservableCollection并将列表框绑定到Mainlist。这是有效的,但我认为这是不好的做法,因为这样我有重复的数据。有什么想法?
答案 0 :(得分:2)
您可以使用CollectionViewSource并添加过滤逻辑来限制显示的项目数。例如,如果您只想显示100个项目:
var cvs = new CollectionViewSource();
cvs.Source = myList; //the raw list from the viewmodel
cvs.Filter += (s, a) => a.Accepted = myList.IndexOf(a.Item) < 100;
listBox2.ItemsSource = cvs.View;
编辑:基于发布的代码
设置Mainlist.Source
时,也会更改Mainlist.View
。因此,在list.ItemsSource
构造函数中设置MainPage
是没用的(此外,View
属性最有可能是null
。为了解决您的问题,您应该将以下这些行移至MainViewModel
构造函数:
this.Mainlist.Source = App.ViewModel.Items;
this.Mainlist.Filter += (s, a) =>
a.Accepted = App.ViewModel.Items.IndexOf((ItemViewModel)a.Item) < 10;
这样,您只需设置Source
一次,View
不会更改。
答案 1 :(得分:0)
我可能会保持简单,并且更多地朝着原始方法的方向前进,做类似的事情:
public MainViewModel()
{
_items = new ObservableCollection<ItemViewModel>();
}
public ObservableCollection<ItemViewModel> Items {
get {return _items;}
private set {_items = value;}
}
private ObservableCollection<ItemViewModel> _items;
private int _items_to_show_on_second_list = 10;
public ObservableCollection<ItemViewModel> ItemsLimit {
get {return _items.Take(_items_to_show_on_second_list);}
private set {_items = value;}
}
请注意,您可能不希望在第二个可观察集合上设置任何内容,由您决定。
好处是您不会改变逻辑,您仍然可以使用Take()
和有意义的变量名称来避免最终被滥用的magic number
。