2009-06-18 6 views
10

コンボボックスでお客様を選択すると、お客様の名前がテキストボックスにと表示されます。私はViewModelのObservableCollectionプロパティでComboxボックスを塗りつぶしますが、私はViewModelでSelectedItemイベントをどのように処理しますか?MVVMでSelectedItemイベントを処理する最も簡単な方法は何ですか?

次のようにコードビハインドで実装するのは簡単ですが、MVVMパターンでこれを行うにはどうすればよいですか?

は、私は現在、私は使用することができ、私の基本的なMVVMテンプレートでDelegateCommandAttachedBehaviorsを持っているが、私は「コンボボックスに新しい項目を選択した」ときにそれらを火に取得する方法を見つけ出すことはできません。

ビュー:背後に

<Window.Resources> 
    <DataTemplate x:Key="CustomerTemplate"> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Text="{Binding LastName}"/> 
     </StackPanel> 
    </DataTemplate> 
</Window.Resources> 

<DockPanel LastChildFill="False" Margin="10"> 
    <ComboBox 
     x:Name="CustomerList" 
     ItemTemplate="{StaticResource CustomerTemplate}" 
     HorizontalAlignment="Left" 
     DockPanel.Dock="Top" 
     Width="200" 
     SelectionChanged="CustomerSelected" 
     ItemsSource="{Binding Customers}"/> 

    <TextBlock x:Name="CurrentlySelectedCustomer"/> 
</DockPanel> 

コード:

private void CustomerSelected(object sender, System.Windows.Controls.SelectionChangedEventArgs e) 
{ 
    Customer customer = (Customer)CustomerList.SelectedItem; 
    CurrentlySelectedCustomer.Text = String.Format("{0} {1}", customer.FirstName, customer.LastName); 
} 

答えて

12

あなたはコンボボックスのSelectedItemプロパティにあなたのViewModel内のプロパティをバインドすることができるはずです。これを双方向バインディングとして設定すると、SelectedItemが変更されたときにプロパティのsetメソッドがトリガーされるため、通知されます。

のViewModel:

public ObservableCollection Customers 
{ 
    get { return _customers; } 
    set 
    { 
     if (_customers != value) 
     { 
      _customers = value; 
      OnPropertyChanged("Customers"); 
     } 
    } 
} 

public Customer SelectedCustomer 
{ 
    get { return _selectedCustomer; } 
    set 
    { 
     if (_selectedCustomer != value) 
     { 
      _selectedCustomer= value; 
      LastName= value.LastName; 
      OnPropertyChanged("SelectedCustomer"); 
     } 
    } 
} 

public Customer LastName 
{ 
    get { return _lastName; } 
    set 
    { 
     if (_lastName!= value) 
     { 
      _lastName= value; 
      OnPropertyChanged("LastName"); 
     } 
    } 
} 

XAML:

<DockPanel LastChildFill="False" Margin="10"> 
    <ComboBox 
     x:Name="CustomerList" 
     ItemTemplate="{StaticResource CustomerTemplate}" 
     HorizontalAlignment="Left" 
     DockPanel.Dock="Top" 
     Width="200" 
     SelectedItem="{Binding SelectedCustomer, Mode=TwoWay}" 
     ItemsSource="{Binding Customers}"/> 

    <TextBlock x:Name="CurrentlySelectedCustomer" 
       Text="{Binding LastName}"/> 
</DockPanel> 
+0

= "True" をIsSynchronizedWithCurrentItemを設定することを忘れないで、現在選択されている項目

ListCollectionView view = (ListCollectionView)CollectionViewSource.GetDefaultView(Customers); view.CurrentChanged += delegate { SelectedCustomer= (Customer)view.CurrentItem; }; 

を検出するためのCollectionViewを使用し

更新

現在選択されている項目を検出するために、CollectionViewを使用します私が探していたものは、それがとてもシンプルであったことを知らなかった。 –

+1

これはV/VM間の依存関係を覚えている。ビュー、CurrentlySelectedCustomerは決して更新されません! CollectionViewを使用すると...ビューがVMにバインドされていなくても機能します。 – rudigrobler

+3

一般に私はCollectionViewに利点があることに同意します(同じリストを複数のセレクタにバインドしたいときはいくつかの条件がありますが)が、あなたのコメントは正しいとは思わない。たとえば、LastNameプロパティが正しく更新されているかどうかを確認するためのテストを書いたければ、ビューが必要なくなり、SelectedCustomerプロパティをテストコードで設定することができます。 –

10

はwww.codeproject.com上thisアプリケーションを見てください。ここで私はただ、また正確

+0

+1はIsSynchronizedWithCurrentItem = "True"の必要性に言及しています。私のコードで 'CurrendChanged'が決して解雇されなかった理由を理解しようとした1時間後、あなたはその日を救ったのです。 – HolySamosa

関連する問題