2012-07-07 138 views
1

这是怎么回事。我有一个视图模型,我称之为webclient,并用项目填充可观察的集合。我需要在两个不同的页面中有两个不同的列表框,但是与viewmodel具有相同的ItemsSource。如何限制两个列表框之一中的项目数量而不影响其他项目?我试图使用.Take(限制)到正在创建项目的视图模型中,但影响两个列表框。如何限制observablecollection数据绑定列表框中的项目数量?

更新

视图模型

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)另一种选择是米AKE新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。这是工作,但我认为这是不好的做法,因为这样我就重复了数据。有关于此的任何想法?

回答

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为好。因此,在MainPage构造函数中设置list.ItemsSource是无用的(此外,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不会改变。

+0

感谢@Eren但在我case“myList”是“App.ViewModel.Items”,它是可观察集合,所以我在IndeOf表达式中得到一个错误 – user1004994 2012-07-07 14:41:43

+0

这应该没问题,因为ObservableCollection确实有一个IndexOf方法。 – 2012-07-07 16:48:50

+0

错误是参数1:无法从'object'转换为'ItemViewModel' – user1004994 2012-07-07 17:06:41

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

请注意,您可能不希望2号观察集合设置任何事情,甚至您。

的好处是,你不改变你的逻辑,你仍然可以有可读的代码(使用Take()和有意义的变量名,以避免最终会被滥用magic number

相关问题