1

データ バインディングと Entity Framework のナビゲーション プロパティに問題があります。

Entity Framework デザイナーによって生成された 2 つのクラスがあります。

クラス Foo :

id (int)
bar (Bar)
...

クラスバー

id (int)
name (string)
...

を使用してObservableCollection<Foo>、データグリッドに次の列を入力しました。

<DataGrid.Columns>
    <DataGridTextColumn Header="Id" Binding="{Binding Path=id}"/>
    <DataGridTemplateColumn Header="Bar">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <ComboBox 
                    SelectedValuePath="Id" 
                    SelectedValue=
                        "{Binding Path=bar.Id, Mode=TwoWay,
                        UpdateSourceTrigger=PropertyChanged}"
                    DisplayMemberPath="name" 
                    ItemsSource=
                        "{Binding Path=BarList, 
                        RelativeSource={RelativeSource FindAncestor, 
                        AncestorType={x:Type Window}}}"
                    Background="White" />
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid.Columns>

ComboBox には が取り込まれObservableCollection<Bar>、現在の が正しく表示されていBarます。

コンボボックスで別のアイテムを選択すると問題が発生します。次のエラーが表示されます。

System.Windows.Data Error: 8 : Cannot save value from target back to source.

System.InvalidOperationException: The property 'Id' is part of the object's key information and cannot be modified

エラーが表示される理由はわかりますが、これを別の方法で処理するにはどうすればよいですか?

Foo編集:との関係Barは N..1 です。つまり、 aFooは 1 または 0Barで、 Bar は複数Fooの s を持つことができます。

現時点では、新しいものを選択することはできませBarFoo

4

3 に答える 3

2

オブジェクトを直接使用したくない場合 (つまり、 and を使用せずSelectedValuePathに直接SelectedValue使用SelectedItem="{Binding Foo.Bar}"する場合は、EF デザイナーに を指示する必要があります。generate foreign key property BarId on the Foo entityその後、SelectedValue="{Binding Foo.BarId}".

于 2012-11-19T20:07:43.030 に答える
2

barプロパティに直接バインドする必要があります。あなたのコードはId、選択した Foo のバーの を変更しようとしていますが、現在の Foo に関連付けられているバーを変更したいのです。Equalsクラスのメソッドもオーバーライドする必要がありますBar

<ComboBox SelectedValue="{Binding bar, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
          DisplayMemberPath="Name"
          ItemsSource="{Binding Path=BarList, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" Background="White" />

そしてあなたのBarクラスで:

public override bool Equals(object obj)
{
    if (obj is Bar)
        return ((Bar)obj).Id == Id;
    return false;
}
于 2012-11-19T11:57:08.157 に答える
0

私には、問題はWPFよりもEntity-Frameworkにあるようです。bar の ID が同時に foo の主キーの一部であることは正しいですか? 少なくともバインディング、ComboBox のセットアップ、およびエラー メッセージは、それを暗示しているようです。

エンティティ フレームワークの制限の 1 つは、キーの更新がサポートされていないことです。オブジェクトのキーを変更したい場合は、基本的にそれを削除し、新しいキーで再作成し、他のすべてのプロパティをコピーする必要があります。私が現在取り組んでいるプログラムでは、Id をプロパティとして公開し、変更されたときに舞台裏でこの処理を行うラッパー クラスを作成することにしました。オブジェクトを切り離して再利用することを提案する投稿を見たことがありますが、私の場合はうまくいきませんでした。

于 2012-11-19T18:58:38.653 に答える