2016-12-23 15 views
0

私は2つのテーブルを持つデータベースを持っています。 tblContactおよびtblPersontblContacttblPersonの間に1対多の関係があります.1人の連絡先には多くの人がいる場合があります。私はデータバインディングを作成するためにVB 2013とEntity Frameworkを使用しています。バインドされた子オブジェクトのComboBox ItemSourceの更新

バインドされたComboBox(cboPerson)の問題は、別の連絡先に移動してから戻るまで人を追加/削除/変更すると更新されません。 ComboBox ItemSourceをリフレッシュするメソッドはありますか?

私が行った変更は、基礎となるオブジェクトとデータベースに反映されていることがわかります。

ここにXAMLがあります。

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:TestBinding" mc:Ignorable="d" x:Class="MainWindow" 
    Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <CollectionViewSource x:Key="ContactView" d:DesignSource="{d:DesignInstance {x:Type local:tblContact}, CreateList=True}"/> 
     <CollectionViewSource x:Key="PersonView" Source="{Binding tblPersons, Source={StaticResource ContactView}}" /> 
    </Window.Resources> 

    <Grid DataContext="{Binding Source={StaticResource ContactView}}"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="Auto" /> 
      <ColumnDefinition Width="*" /> 
     </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="Auto" /> 
      <RowDefinition Height="Auto" /> 
      <RowDefinition Height="Auto" /> 
      <RowDefinition Height="*" /> 
     </Grid.RowDefinitions> 

     <Label Grid.Row="0" Margin="3" Grid.Column="0" Content="Contact ID:"/> 
     <TextBox Grid.Row="0" Margin="3" Grid.Column="1" Padding="3" x:Name="txtContactID" VerticalAlignment="Center" Text="{Binding Contact_ID, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}" /> 

     <Label Grid.Row="1" Grid.Column="0" Margin="3" Content="Person ID:" /> 
     <ComboBox Grid.Row="1" Grid.Column="1" Margin="3" Padding="3" x:Name="cboPerson" SelectedValue="{Binding Contact_Primary_Person}" ItemsSource="{Binding Source={StaticResource ContactView}, Path=tblPersons, Mode=TwoWay}" SelectedValuePath="Person_ID" DisplayMemberPath="Person_Salutation" /> 

     <StackPanel Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Orientation="Horizontal" > 
      <Button Margin="3" Padding="3" Name="btnAdd">Add</Button> 
      <Button Margin="3" Padding="3" Name="btnPrev">Prev</Button> 
      <Button Margin="3" Padding="3" Name="btnNext">Next</Button> 
      <Button Margin="3" Padding="3" Name="btnDelete">Delete</Button> 

     </StackPanel> 
    </Grid> 
</Window> 

フォームの背後にあるコード。

​​

アドバイスや説明をいただければ幸いです。

+0

コードを少なく掲示した方が役に立ちます。問題に関連するコードだけが、クラス全体を辿るのではなく、これをもっと簡単に答えることができます。 – David

答えて

0

ComboBox ItemSourceをリフレッシュする方法はありますか?

あなたは、そのビューにRefreshメソッドを呼び出すことにより、CollectionViewSourceをリフレッシュできます。

ContactView.View.Refresh() 

他のオプションは、(tblPersonの)のObservableCollectionにCollectionViewSourceのソースを設定して追加することを忘れないことです新しいtblPersonオブジェクトをこのコレクションに追加してからデータベースに追加します。

+0

返信いただきありがとうございます。私は_context.SaveChanges()の直後にこれを追加しましたが、コンボボックスの内容に更新されませんでした。私はObservableCollectionへの変更を調べるつもりです。 –

+0

新しいアイテムをデータベースに追加すると、tblContactsコレクションのローカルコピーは変更されません。 CollectionViewSourceを更新するには、レコードを再度取得する必要があります。ContactView.Source = _context.tblContacts.ToList();そのため、ObservableCollectionをソースとして使用し、データベースを更新するときに、新しいアイテムをこのアイテムに追加することを忘れないでください。 – mm8

0

コレクション(たとえば、コンボボックスアイテム)にバインドすると、このコレクション内の個々のアイテムを変更するとこのコレクションは更新されません。これは、コレクション内のアイテムが変更されている場合でも、バインドしたコレクションオブジェクトがまだ同じであるためです。プロパティの変更通知は決して発生しないため、コントロールには変更が通知されません。別の連絡先に変更すると、実際にオブジェクト全体が変更され、プロパティ変更イベントがトリガーされます。これは、コレクションのバインディングを使用するときには、かなり一般的な「落とし穴」です。

コレクション内の値が変更されたときにコレクションに通知する場合は、最も一般的な解決方法はObservableCollectionを使用することです。これには、プロパティの変更通知が組み込まれています。

オブジェクトがEFオブジェクトであり、それらがあなたのために作成された場合、NuGetパッケージ "propertychanged.fody"のインストールを検討することができます。これにより、[ImplementPropertyChanged]属性を設定するだけで、すべてのクラスにプロパティ変更通知を追加することができます。

EFクラスは部分クラスであるため、2番目のファイルを作成してプロパティ変更通知を追加することができます。

結果(fodyを追加した後)は、次のようなファイルを作成することになります(名前空間などを追加する必要があります)。

[ImplementPropertyChanged] 
public partial class tblContact 
{ 
} 

これは文字通りすべての操作です。 tblContactのすべてのプロパティは、プロパティ変更通知を持つようになりました。あなたの人のタイプについて同じことをする必要があるかもしれません。

部分クラスを使用すると、デザイナによって生成されたEFクラスの動作を拡張できます。部分クラスを初めて使う人は、クラス定義を2つ以上のファイルに分割する方法です。デザイナーによって作成された部分は編集しませんが、ファイル内で自分が好きなことをすることができます。部分クラスの名前は、コンパイラが実際に同じクラスであることが分かるように、同じである必要があります。

+0

返事ありがとうございます。私はこれについて考えていましたが、Entity Frameworkがオブジェクトを作成して以来、コレクションをObervableCollectionにするために何を変更する必要があるのか​​分かりません。私は静かなカップルを持っているので、私はEFが作成したオブジェクトを見ていきます。 –

+0

更新をありがとうございます、私は今日これを探検します。 –

0

私は、このページEntity Framework Databinding with WPFを発見し、私はをデータバインディングの見出し更新コード生成の下の指示に従いました。

私はまた、生成されたクラスtblContact.vbに

Imports System.Collections.ObjectModel 

を追加する必要がありました。

tblPersonを追加、削除、および更新すると、コンボボックスが自動的に更新されるようになりました。

関連する問題