2012-07-07 58 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

相關問題