2017-07-14 5 views
0

GitHubのリンクに同じコレクションをバインド:https://github.com/babakin34/wpf_test/tree/master/WpfApp1コンボボックスやデータグリッド

I持って、次のクラス:

のviewmodels


public class PersonVM : BindableBase 
{ 
    public int ID { get; set; } 

    private string _lastName; 
    public string LastName 
    { 
     get { return _lastName; } 
     set { SetProperty(ref _lastName, value); } 
    } 
} 

public class MainVM : BindableBase 
{ 
    public ObservableCollection<PersonVM> People { get; set; } 

    private PersonVM _selectedPerson; 
    public PersonVM SelectedPerson 
    { 
     get { return _selectedPerson; } 
     set { SetProperty(ref _selectedPerson, value); } 
    } 

    public MainVM() 
    { 
     People = new ObservableCollection<PersonVM>() 
     { 
      new PersonVM() 
      { 
       ID = 1, 
       LastName = "AA" 
      }, 
      new PersonVM() 
      { 
       ID = 2, 
       LastName = "BB" 
      }, 
     }; 

     SelectedPerson = People.First(); 
    } 
} 

VIEW


<Grid> 
    <StackPanel> 
     <ComboBox ItemsSource="{Binding People}" 
        SelectedItem="{Binding SelectedPerson}" 
        DisplayMemberPath="LastName" 
        Margin="0,5,0,25"/> 

     <DataGrid ItemsSource="{Binding People}"/> 
    </StackPanel> 
</Grid> 


どのように私は、ユーザーがデータグリッドのデフォルトの最後のエントリによって引き起こされる空の要素を、選択したときにコンボボックスから「MainVM.SelectedPerson」が通知されていることを達成することができますか?

PS:私はプリズムを使用していますが、問題はプリズム関連ではありません。 BindableBaseをINotifyPropertyChangedに置き換えることができます。

+0

これは、ComboBoxで選択できる実際のPersonVMではなく、DataGridに新しい項目を追加するためのプレースホルダです。 – mm8

+0

@ mm8:DataGridの最後の行が必要なので、ユーザーは新しいエントリを追加できます。 –

+0

この行を選択すると、ComboBoxに何を表示すると思われますか? – mm8

答えて

2

編集: ここの本当の問題は、私が最初に思っていたものとは少し異なります。挿入行を選択すると、WPFが「NamedObject」を「PersonVM」にキャストできないことが出力ウィンドウに表示されます。 Datagridは挿入行のNamedObjectを作成しますが、バインディングは間違った型のため動作しません。 クリーンで簡単な解決策は、オブジェクトのタイプがPersonVMであるかどうかを確認するコンバータを作成することです。それ以外の場合は、NamedObjectインスタンスではなくnullを返します。

public class MyConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return value; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value is PersonVM) 
      return value; 
     return null; 
    } 
} 

とXAMLで

<DataGrid x:Name="DataGrid" 
        ItemsSource="{Binding People}" 
        SelectedCellsChanged="DataGrid_OnSelectedCellsChanged" 
        SelectedItem="{Binding SelectedPerson, 
             Converter={StaticResource myConverter}}" 


古いと汚い

ない素敵な方法がありますが、のviewmodelを使用して(あるいは抽象化する気にならないのであればインターフェイス経由で)を使用して、 "SelectionChanged"イベントを使用してViewModelのSelectedPersonをnullに設定することができます。 f選択した項目のいずれも必要なタイプではありません。

private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     bool invalidStuffSelected = false; 
     //throw new System.NotImplementedException(); 
     foreach (var obj in DataGrid.SelectedItems) 
     { 
      if (!(obj is PersonVM)) 
       invalidStuffSelected = true; 
     } 
     MainVM vm = (MainVM) this.DataContext; 
     if (invalidStuffSelected) 
      vm.SelectedPerson = null; 
    } 
あなたの例では、コンボボックスが選択された1つの値しか表示できないため、selectionmode "single"が意味を持ちます。
+0

私はすでに同様の方法でそれを解決しました。コードの背後にあるコードや汚れたハックを使わなければ可能かどうかを知りたかっただけです。 –

+0

上記の私の編集された答えを見てください – manni

関連する問題