2017-02-24 16 views
0

私はcustomsboxのitemsourceがviewmodelのobservablecollectionにバインドされています。 customListboxにSelectedItemsList DependencyPropertyを作成して、ユーザーがアイテムを選択できるようにし、viewmodelが更新されるようにしました。これは完全に機能します。リストボックスから選択されたアイテムのバインディングの更新

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から選択した項目を更新する方法はありますか?より適しているリストボックスの代わりがありますか?

+0

SelectedItemsListプロパティのPropertyChangedCallbackで、割り当てられたコレクションがINotifyCollectionChangedを実装しているかどうかを確認します(例: ObservableCollectionでは)、CollectionChangedハンドラをアタッチします。そのハンドラで、SelectedItemsコレクションにアイテムを追加または削除します。 「SelectedItemsをバインドする」のStackOverflowを検索します。この問題には既に他の質問と回答があります。 – Clemens

+0

propertyChangedCallbackは、ウィンドウの初期化でのみ呼び出されるようです。 dependency.registerの呼び出しが適切であることを確認するコードをいくつか投稿します。 – kurgaan

+0

シュート。私はそれを考え出した。私は間違った観察可能なコレクションに縛られていた。 – kurgaan

答えて

0

誰かを助ける場合に備えて私のソリューションを投稿すると思いました。ここで

は私の非常に単純なItemクラスは、ここで

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

バインディングです
関連する問題