2008-08-27 18 views
6

データバインドされたDataGridViewで外部キーの参照を表示できるようにするWinFormsアプリケーション(.Net 3.5、WPFなし)を開発しています。WinFormsデータバインディングと外部キーの関係

私はOrderLinesのテーブルを持っているということです。注文行には、製品と外部キーの関係があり、ProductはProductTypesとの外部キー関係を持っています。

私はDataBound DataGridViewを持っています。各行は注文ラインを表し、ラインの製品と製品タイプを表示します。

ユーザーは、グリッドに直接注文線を追加または編集し、comboBoxColumnから注文行の製品を選択することができます。これにより、選択した製品の製品タイプを示すproducttype列が同じ行に更新されます。

私が今までに見つけたことに最も近いのは、注文線を表すドメインオブジェクトを導入し、DataGridViewをこれらの注文線のコレクションにバインドすることです。次に、製品と製品タイプを公開しているorderlineオブジェクトにプロパティを追加し、関連するnotifypropertychangedイベントを発生させて、最新の状態に保ちます。私のオーダーラインリポジトリでは、このオーダーラインオブジェクトとデータベースの3つのテーブルの間のマッピングを結びつけることができます。

これは物事のデータバインディング側では機能しますが、リポジトリ内のすべてのORマッピングが悪いと思われるコードを手渡す必要があります。私はnHibernateがこの配線を助けることができると思ったが、すべての外部キーを介したマッピングに苦労している - 注文ラインの製品に対する外部キーの参照は、外部キーに基づいて正しい製品オブジェクトを作成する)データバインディングを実行しようとすると、databound idカラムを取得して製品または製品タイプのオブジェクトを更新できません。

私の一般的なアプローチは適切な球場でさえですか?そうであれば、マッピング問題の良い解決策は何ですか?

また、私が考慮していない外部キーの参照を含むデータバインディングの方が良いソリューションがありますか?

答えて

2

グリッドにバインドしているときにINotifyPropertyChangedをサポートするには不十分ですが、IBindingList実装でListChangedイベントを発生させてオーバーライドして戻す必要があるSupportsChangeNotificationプロパティの場合はtrueです。これに対してtrueを返さないと、グリッドはデータが変更されたかどうかを調べません。

.NET 2.0以降では、BindingListクラスを使用してジェネリックコレクションを作成することができます。これはほとんどの不自由さを解決します(オーバーライドして、SupportsChangeNotificationプロパティのtrueを返すことを忘れないでください)。

データバインディングに使用するクラスにコレクション(IBindingListやBindingListなど)のプロパティがある場合は、外部キーグリッドをそのプロパティに直接バインドできます。Formsデザイナーでバインディングを構成するときは、コレクションプロパティをグリッドのデータソースとして選択するだけです。それは "うまくいく"べきである。唯一の卑劣な部分は、空のコレクションまたはヌルコレクションを正しい方法で処理することです。

+0

Garo - ありがとうございました。唯一の違いは、グリッドではなく、外部キーの列があることです。 私は私の問題を引き起こしていた原因を明確にして、私の元の応答も更新するつもりです。私が最初にこの問題を誤診した理由が有用かもしれないと思います –

1

にStackOverflowに歓迎:)

あなたがどうなるのか。通常

はダウン二つの値ValueMember and DisplayMemberのドロップの情報拠点です。

ValueMemberは、実際のコントロール値のソースです(これは注文行のキー値になります)。表示メンバーは値ではなくユーザーに表示される値です(これはFK値)。

必要なデータをすべて返して、これらのプロパティを設定することはできません。ここで

0

私の元の質問は、明らかにそのことについて申し訳ありませんが、明確ではありませんでした。

一般的なDataGridViewへのデータバインディングや、DataGridViewComboBoxColumnの実装では問題はありませんでした。これは、すでに正式に回答した人がWeb上で十分に文書化されているためです。

私が解決しようとしてきた問題は、関係を通して掘り下げているプロパティのリフレッシュです。

「Product」列の値を変更すると、コードではプロパティを設定していて、NotifyPropertyChangedイベントが発生していますが、「Product Type」列は更新されません。 (デバッグ時に私はすべての適切な場所に行きます)

私は、データソースの "Product Type"プロパティを直接設定すると、これがうまくいかないことに気づいたのですが、 "Product" "セッター。

私が正しい道に戻ってきたと思うもう一つのことは、メインフォームで作成された偽のデータアクセス層を提供するとすべて正常に動作することです。

また、nHibernateで作成されたIListをIBindingListにコピーすると、すべてが正常に表示されます。

ので問題は、私はスレッドを考えると、特定のデータソースを使用した場合NotifyPropertyChangedイベントが特定の方法では、失われつつある(私はそれよりももっと決定的な可能性がしたい!)私は研究を続けるつもりだ

これを解決するより良い方法は、IListをIBindingListにコピーするよりも、おそらくスレッドマーシャリングについて学ぶ必要があります。

編集

私は今、問題を解決し、私は私を混乱させたかを理解考えるソリューションを開発しました - 基本的には、基本的なプロパティのデータバインディングが、何が「上がらないリストにうまく再生されないことが表示されますBindingListから派生したもの - チェーン化されたNotifyPropertyChangedイベントを発生させたプロパティにデータバインドをしようとすると、物事はひどくなってしまい、イベントが失われました。

私が今使っているデータアクセスソリューションは、Rob Conery IRepositoryパターンのバリエーションを使用して、自分のカスタムクラスとしてバインドされたコレクションを返します。SortableBindingLazyListはBindingListから派生し、Sort Coreメソッドを実装し、その内部リストをクエリとして使用し、リストのマテリアライゼーションを遅延させます。

0

まあ、私はそれはDataGridViewのでサポートされているのかどうかわかりませんが、あなたは(通常のテキストボックスに、と言う)は、正規のWinFormsデータバインディングをやっているときは、オブジェクトの関係をナビゲートするプロパティパスを使用することができます。このような

何か:これはあまりにもあなたの状況で動作するかどう

myTextBox.DataBindings.Add("Text", anOrderLine, "OrderedPart.PartNumber"); 

が見て価値があるだろう。

関連する問題