2017-02-24 109 views
0

我有一個自定義列表框,其itemssource綁定到viewmodel中的observablecollection。我在customListbox中創建了SelectedItemsList DependencyProperty,以便用戶可以選擇項目並更新視圖模型。這工作完美。listbox選擇項綁定從源更新

我還希望viewmodel中的綁定列表在更改時更新customListbox中的選定項。

static FrameworkPropertyMetadata fpm = new FrameworkPropertyMetadata(
       new ObservableCollection<MyItem>(), 
       (FrameworkPropertyMetadataOptions.AffectsRender | 
       FrameworkPropertyMetadataOptions.BindsTwoWayByDefault), 
       new PropertyChangedCallback(OnSelectedItemsChanged) 
       ); 

    private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
       //the code 
    } 


    public static readonly DependencyProperty SelectedItemsListProperty = 
      DependencyProperty.Register("SelectedItemsList", 
      typeof(ObservableCollection<MyItem>), 
      typeof(CustomListBox), fpm); 

SelectedItems是隻讀的。無論如何都要更新viewModel中的選定項目嗎?有沒有替代ListBox,會更合適?

+0

在SelectedItemsList屬性的PropertyChangedCallback中,檢查分配的集合是否實現INotifyCollectionChanged(例如, ObservableCollection),並附加一個CollectionChanged處理程序。在該處理程序中,將項目添加到SelectedItems集合或從SelectedItems集合中刪除項目。搜索StackOverflow以「綁定SelectedItems」。這個問題已經有其他問題和答案。 – Clemens

+0

propertyChangedCallback似乎只在Windows的初始化中被調用。我會發布一些代碼來確認我的dependency.register調用是否合適。 – kurgaan

+0

拍攝。我想到了。我被綁定到錯誤的可觀察集合。 – kurgaan

回答

0

我想我會發布我的解決方案,以防萬一它幫助任何人。

這是我非常簡單的項目類

class MyItem 
{ 
    public string MyString { get; set; } 
    public MyItem(string m) 
    { 
     MyString = m; 
    } 
} 

這是我CustomListBox代碼

class CustomListBox : ListBox 
{ 
    public CustomListBox() 
    { 
     this.SelectionChanged += CustomListBox_SelectionChanged; 
    } 

    void CustomListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     ObservableCollection<MyItem> tempList = new ObservableCollection<MyItem>(); 

     foreach (MyItem i in this.SelectedItems) 
     { 
      tempList.Add(i); 
     } 

     this.SelectedItemsList = tempList; 
    } 
    #region SelectedItemsList 

    public ObservableCollection<MyItem> SelectedItemsList 
    { 
     get { return (ObservableCollection<MyItem>)GetValue(SelectedItemsListProperty); } 
     set { SetValue(SelectedItemsListProperty, value); } 
    } 

    public static readonly DependencyProperty SelectedItemsListProperty = 
     DependencyProperty.Register("SelectedItemsList", typeof(ObservableCollection<MyItem>), typeof(CustomListBox), 
     new PropertyMetadata(new ObservableCollection<MyItem>(), new PropertyChangedCallback(OnSelectionChanged))); 

    public static void OnSelectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     CustomListBox clb = d as CustomListBox; 
     var selectedItems = e.NewValue as ObservableCollection<MyItem>; 
     if (selectedItems != null) 
     { 
      clb.SetSelectedItems(selectedItems); 
     } 
    } 
    #endregion 
} 

的XAML在我的窗口

<local:CustomListBox Height="500" Width="200" x:Name="listview" Margin="0,40,0,0" ItemsSource="{Binding MyItemsList}" 
          Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" TabIndex="50" 
          SelectionMode="Multiple" SelectedItemsList="{Binding SelectedMyItems, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  > 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding Path=MyString}" /> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </local:CustomListBox> 

約束力和我的ViewModel

class MyViewModel : ViewModelBase 
{ 

    public MyViewModel() 
    { 
     this.SelectChangeMyItemsCommand = new BaseCommand(new Action(SelectChangeMyItems)); 
    } 

    private ObservableCollection<MyItem> selectedMyItems = null; 

    public ObservableCollection<MyItem> SelectedMyItems 
    { 
     get 
     { 
      if (selectedMyItems == null) 
      { 
       selectedMyItems = new ObservableCollection<MyItem>(); 
      } 
      return selectedMyItems; 
     } 

     set 
     { 
      selectedMyItems = value; 
      OnPropertyChanged("SelectedMyItems"); 
     } 
    } 

    private ObservableCollection<MyItem> myItemsList = null; 

    public ObservableCollection<MyItem> MyItemsList 
    { 
     get 
     { 
      if (myItemsList == null) 
      { 
       MyItemsRefresh(); 
      } 
      return myItemsList; 
     } 

     set 
     { 
      myItemsList = value; 
      OnPropertyChanged("MyItemsList"); 
     } 
    } 

    public void MyItemsRefresh() 
    { 
     ObservableCollection<MyItem> tempMyList = new ObservableCollection<MyItem>(); 
     tempMyList.Add(new MyItem("Angry Apple")); 
     tempMyList.Add(new MyItem("Big Bird")); 
     tempMyList.Add(new MyItem("Candy Cane")); 
     tempMyList.Add(new MyItem("Daring Dart")); 


     MyItemsList = tempMyList; 
    } 

    private static bool iseven = true; 
    public ICommand SelectChangeMyItemsCommand { get; private set; } 
    public void SelectChangeMyItems() 
    { 

     ObservableCollection<MyItem> items = new ObservableCollection<MyItem>(); 
     for(int i = 0; i < myItemsList.Count; i++) 
     { 
      if (iseven && IsEven(i)) 
      { 
       items.Add(MyItemsList[i]); 
      } 
      else if (!iseven && !IsEven(i)) 
      { 
       items.Add(MyItemsList[i]); 
      } 
     } 
     this.SelectedMyItems = items; 
     iseven = !iseven; 
    } 

    public static bool IsEven(int value) 
    { 
     return value % 2 == 0; 
    } 
}