2017-02-09 8 views
0

これは私が立ち往生しているのではなく、もっと良い方法があるかどうかという疑問です。それはそのままでは機能しますが、できるかぎりもっと理解したいと思います。ComboBoxの変更時にObservableCollectionを変更する

バインドにObservableCollection<T>を使用しているときに、いつもDataGrid.ItemSourceを更新する必要がありますか?

ObservableCollection<T>DataGridにバインドするには、次のコードを使用してください。

public partial class MainWindow : INotifyPropertyChanged 
{ 
    public MainWindow() 
    { 
     DataContext = this; 
     InitializeComponent(); 

     CalcObservable = 
      DatabaseQueries.ShiftInputSourceObserv(SelectedEmployee.Key, DateFilter); 

     MyDataGrid.ItemsSource = CalcObservable; 
    } 

    public ObservableCollection<CalcTable> CalcObservable { get; set; } 
      = new ObservableCollection<CalcTable>(); 
} 

そして、これは、データベースからデータを取得する機能である、

internal class DatabaseQueries 
{ 
    public static ObservableCollection<CalcTable> ShiftInputSourceObserv(int staffNo, DateTime date) 
    { 
     using (DatabaseDataContext dataContext = new DatabaseDataContext(MainWindow.InstanceConnectionString)) 
     { 
      return new ObservableCollection<CalcTable> 
        (dataContext.CalcTables.Where(
         p => p.Staff_No == staffNo && 
         p.Year_No == date.Year && 
         p.Month_No == date.Month) 
         .OrderBy(p => p.Column_Index)); 
     } 
    } 
} 

私はその後、ObservableCollection<T>を更新するために、ComboBox変更イベントを使用します。 SelectedEmployee.KeyComboBoxにバインドされ、選択すると、選択した従業員が変更されています

private void NumbersComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
     CalcObservable = 
     DatabaseQueries.ShiftInputSourceObserv(SelectedEmployee.Key, DateFilter); 

     MyDataGrid.ItemsSource = CalcObservable; 
} 

私はObservableCollection<T>を変更すると、再びMyDataGrid.ItemsSource = CalcObservable;ラインを使用する必要がなしを更新してしまうという印象の下にありましたか?

ありがとうございます。

+0

新しいインスタンスではありませんか? – Ron

+0

'NumbersComboBox_SelectionChanged'に' CalcObservable'を代入するのではなく、既存のコレクションをクリアし、 'DatabaseQueries.ShiftInputSourceObserv'の戻り値の項目を既存のコレクション(すなわち' CalcObservable ')に追加してみてください。 –

+0

' ObservableCollection 'アイテムを追加/削除するときのUI。しかし、あなたがやっていることは、新しいインスタンスを作成することです。 – Pikoh

答えて

3

私は

いいえ、あなたはそれを結合しない...以下のコードを使用して ObservableCollection<T> DataGridに結合しています。 ItemsSourceプロパティを CalcObservableプロパティの値に設定します。

次に、あなたのNumbersComboBox_SelectionChangedイベントハンドラで新しいObservableCollection<T>CalcObservableプロパティを設定しています。これにより、DataGridItemsSourceプロパティが自動的に更新されることはありません。

あなたが実際にあなたがDataGridがあなたのクラスがINotifyPropertyChangedインターフェイスを実装し、あなたがCalcObservableプロパティのセッターでPropertyChangedイベントを発生させることを提供リフレッシュできCalcObservable財産へバインド行う場合:

public partial class MainWindow : Window, INotifyPropertyChanged 
{ 
    public MainWindow() 
    { 
     DataContext = this; 
     InitializeComponent(); 

     CalcObservable = DatabaseQueries.ShiftInputSourceObserv(SelectedEmployee.Key, DateFilter); 
     MyDataGrid.SetBinding(ComboBox.ItemsSourceProperty, new Binding(nameof(CalcObservable)) { Source = this }); 
    } 

    private ObservableCollection<CalcTable> _calcObservable = new ObservableCollection<CalcTable>(); 
    public ObservableCollection<CalcTable> CalcObservable 
    { 
     get { return _calcObservable; } 
     set { _calcObservable = value; OnPropertyChanged(nameof(CalcObservable)); } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string name) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(name)); 
    } 
} 

他のオプションは、ObservableCollection<T>の既存のインスタンスをクリアし、DataGridを更新するたびに新しいコレクションを作成するのではなく、新しいアイテムを追加することです。

+0

私に少し教えてください、私はこれを実装しようとしています。私は正直に言うと、それは私の頭の上を少し行きます。あなたがデータグリッドにバインディングを設定する方法。 – KyloRen

+0

バインディングをプログラムで定義する方法*です。 XAMLマークアップでバインディングを設定することもできます。しかし、XAMLマークアップで定義したバインディングをクリアするので、ItemsSourceプロパティをプログラムで設定しないでください。 – mm8

+0

コメントで問題を解決しましたが、あなたの答えは非常に興味深いものです。あなたが知っているように、1つの 'OnPropertyChanged'メソッドだけを使用することができ、あなたが表示するメソッドは私の他の' OnPropertyChanged'プロパティが動作することを許可しません。なぜObservableCollection をそのように設定しましたか?これは、ObservableCollection '' InotifyPropertyChanged'を自動的に実装するので、これを行う古い方法ではありませんか?私はあなたが示した助けのためにupvotedが、私はこの答えをもっと理解したい。 – KyloRen

関連する問題