2015-11-05 80 views
0

這裏是我的View的源代碼。WPF ListView SelectedItems DataBinding MVVM

<ListView SelectionMode="Multiple" 
    ItemsSource="{Binding Items, Mode=OneWay}" 
    SelectedItems="{Binding SelectedItems}"> 
     <ListView.ItemTemplate> 
      <DataTemplate> 
       <Grid Height="55" Margin="-3,0,-3,0"> 
        <TextBlock Text="{Binding Name}"/> 
       </Grid> 
      </DataTemplate> 
     </ListView.ItemTemplate> 
</ListView> 

我已經盡力了SelectedItems-Property綁定到我的ViewModel。 的源代碼:

ObservableCollection<string> _selectedItems = new ObservableCollection<string>(); 
    public ObservableCollection<string> SelectedItems 
    { 
     get { return _selectedItems; } 
     set 
     { 
      _selectedItems = value; 
      ***... 
      need to do some operaions here ... 
      ...*** 
      OnPropertyChanged("SelectedItems"); 
     } 
    } 

我需要在SelectedItems-Property(ViewModel)內做一些操作。 我怎樣才能到達那裏?

+0

哪些操作? –

+0

這並不重要,因爲我發佈的源代碼不是完整的(不是真正的)。實際上,SelectedItems不僅僅是一個字符串的ObservableCollection,而是一些特定對象的集合。我需要獲得這些對象。即使你在setter中設置了斷點,也不能停止程序。 – ManDani

+0

哦,我明白了。所以你的問題是綁定似乎沒有工作?這從你的問題不完全清楚。我認爲你已經實現了INotifyPropertyChanged(它看起來像)? –

回答

2

我們與附加屬性看起來像解決它:

public class MultiSelectorExtension 
{ 
    public static readonly DependencyProperty SelectedItemsProperty = 
     DependencyProperty.RegisterAttached("SelectedItems", typeof(INotifyCollectionChanged), typeof(MultiSelectorExtension), 
     new PropertyMetadata(default(INotifyCollectionChanged), OnSelectedItemsChanged)); 

    public static void SetSelectedItems(DependencyObject element, INotifyCollectionChanged value) 
    { 
     element.SetValue(SelectedItemsProperty, value); 
    } 

    public static INotifyCollectionChanged GetSelectedItems(DependencyObject element) 
    { 
     return (INotifyCollectionChanged)element.GetValue(SelectedItemsProperty); 
    } 

    private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     MultiSelector multiSelectorControl = d as MultiSelector; 

     NotifyCollectionChangedEventHandler handler = (sender, 
      args) => 
     { 
      if (multiSelectorControl != null) 
      { 
       IList listSelectedItems = multiSelectorControl.SelectedItems; 
       if (args.OldItems != null) 
       { 
        foreach (var item in args.OldItems) 
        { 
         if (listSelectedItems.Contains(item)) 
         { 
          listSelectedItems.Remove(item); 
         } 
        } 
       } 

       if (args.NewItems != null) 
       { 
        foreach (var item in args.NewItems) 
        { 
         if (!listSelectedItems.Contains(item)) 
         { 
          listSelectedItems.Add(item); 
         } 
        } 
       } 
      } 
     }; 

     if (e.OldValue == null && multiSelectorControl != null) 
     { 
      multiSelectorControl.SelectionChanged += OnSelectionChanged; 
     } 

     if (e.OldValue is INotifyCollectionChanged) 
     { 
      (e.OldValue as INotifyCollectionChanged).CollectionChanged -= handler; 
     } 

     if (e.NewValue is INotifyCollectionChanged) 
     { 
      (e.NewValue as INotifyCollectionChanged).CollectionChanged += handler; 
     } 

    } 

    private static void OnSelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     DependencyObject d = sender as DependencyObject; 

     if (GetSelectionChangedInProgress(d)) 
      return; 

     // Internal Flag to avoid infinite loop 
     SetSelectionChangedInProgress(d, true); 

     dynamic selectedItems = GetSelectedItems(d); 

     try 
     { 
      foreach (var item in e.RemovedItems.Cast<dynamic>().Where(item => selectedItems.Contains(item))) 
      { 
       selectedItems.Remove(item); 
      } 
     } 
     catch (Exception) 
     { 

     } 

     try 
     { 
      foreach (var item in e.AddedItems.Cast<dynamic>().Where(item => !selectedItems.Contains(item))) 
      { 
       selectedItems.Add(item); 
      } 
     } 
     catch (Exception) 
     { 
     } 


     SetSelectionChangedInProgress(d, false); 
    } 


    private static readonly DependencyProperty SelectionChangedInProgressProperty = 
     DependencyProperty.RegisterAttached("SelectionChangedInProgress", typeof(bool), typeof(MultiSelectorExtension), new PropertyMetadata(default(bool))); 

    private static void SetSelectionChangedInProgress(DependencyObject element, 
     bool value) 
    { 
     element.SetValue(SelectionChangedInProgressProperty, value); 
    } 

    private static bool GetSelectionChangedInProgress(DependencyObject element) 
    { 
     return (bool)element.GetValue(SelectionChangedInProgressProperty); 
    } 
} 

而且我們使用在DataGrid樣子:

AttachedProperties:MultiSelectorExtension.SelectedItems="{Binding SelectedPersonss, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
+0

謝謝 - 有效!如果我調試我的程序,我發現SelectedItems-Property具有從ListView中選擇的所有項目。如果用戶選擇或取消選擇項目,是否有辦法提出事件?我需要處理ViewModel中ListView選擇的更改。正如我提到的,如果在我的setter中設置了一個斷點,那麼程序不會停在那裏。 – ManDani

+0

如果這個答案是答案你的解決方案標記爲接受爲其他疑問和疑問問另一個問題! –