listbox选择项绑定从源更新

问题描述:

我有一个自定义列表框,其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集合中删除项目。搜索*以“绑定SelectedItems”。这个问题已经有其他问题和答案。 – Clemens

+0

propertyChangedCallback似乎只在Windows的初始化中被调用。我会发布一些代码来确认我的dependency.register调用是否合适。 – kurgaan

+0

拍摄。我想到了。我被绑定到错误的可观察集合。 – kurgaan

我想我会发布我的解决方案,以防万一它帮助任何人。

这是我非常简单的项目类

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