6

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

このような関係の例として、OrderLines のテーブルがあります。Orderlines には Products に対する外部キー関係があり、Products には ProductTypes に対する外部キー関係があります。

各行がオーダーラインを表し、ラインの製品と製品タイプを表示する、データバインドされた DataGridView が必要です。

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

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

これはデータバインディングの側面では機能しますが、リポジトリ内のすべての OR マッピングをコードに渡さなければならないのは良くないようです。nHibernate はこの接続に役立つと思っていましたが、すべての外部キーを介したマッピングに苦労しています - それらは正常に動作しているようです (オーダーラインの製品の外部キー検索は、外部キーに基づいて正しい製品オブジェクトを作成します)。データバインドを実行しようとしましたが、データバインドされた ID 列を取得して製品または製品タイプ オブジェクトを更新できません。

私の一般的なアプローチは正しい球場でもありますか? もしそうなら、マッピングの問題に対する良い解決策は何ですか?

または、考慮していない外部キー検索を含む行をデータバインドするためのより良い解決策はありますか?

4

5 に答える 5

2

あなたが抱えている問題は、グリッドにバインドしているときに INotifyPropertyChanged をサポートするだけでは不十分であると思いますが、IBindingList実装で ListChanged イベントを発生させ、オーバーライドしてSupportsChangeNotificationに対して true を返すようにする必要があります。財産。これに対して true を返さない場合、グリッドはデータが変更されたかどうかを知るためにそれを探しません。

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

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

于 2008-11-11T19:51:11.033 に答える
1

StackOverflow へようこそ :)

通常は、ドロップダウンの情報をValueMember と DisplayMemberの 2 つの値に基づいて作成します。

ValueMember は実際のコントロール値のソースです (これはオーダー ラインのキー値になります)。表示メンバーは、値の代わりにユーザーに表示される値です (これは FK 値になります)。

必要なすべてのデータを返してこれらのプロパティを設定できない特別な理由はありませんか?

于 2008-08-27T07:15:50.937 に答える
0

DataGridViewでサポートされているかどうかはわかりませんが、通常のWinFormsデータバインディング(たとえば、通常のTextBox)を実行している場合は、プロパティパスを使用してオブジェクトの関係をナビゲートできます。

このようなもの:

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

これがあなたの状況でも機能するかどうかを確認する価値があります。

于 2008-10-22T09:55:01.537 に答える
0

私の最初の質問は明らかに明確ではありませんでした。申し訳ありません。

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

私が解決しようとしてきた問題は、関係を掘り下げているプロパティの更新です。

私の注文の例では、「製品」列の値を変更すると、「製品タイプ」列は更新されません - コードでプロパティを設定して NotifyPropertyChanged イベントを発生させているにもかかわらずです。(デバッグでは、すべての適切な場所に移動します)

いろいろ調べてみたところ、「製品」セッターで設定するのではなく、データソースの「製品タイプ」プロパティを直接設定しても、これが機能しないことに気付きました。

私が正しい軌道に戻ったと私が信じているもう1つのことは、メインフォームで作成されたモック化されたデータアクセスレイヤーを提供すると、すべてが正常に機能することです。

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

したがって、問題は、特定の方法で特定のデータソースを使用すると、スレッド化と NotifyPropertyChanged イベントが失われることだと思います (それよりも決定的なことができればいいのに!)

IList を IBindingList にコピーするよりも、これを解決するためのより良い方法を研究し続けます。スレッド マーシャリングについて学ぶ必要があるかもしれません。

編集

私は今、問題を解決するソリューションを開発し、何が私を混乱させていたかを理解していると思います.BindingListから派生していないリストでは、基本的なプロパティデータバインディング以外はうまく機能しないようです.チェーンされた NotifyPropertyChanged イベントを発生させたプロパティにデータバインドすると、事態は混乱し、イベントが失われました。

私が現在持っているデータ アクセス ソリューションは、Rob Conery IRepositoryパターンのバリエーションを使用しており、作成したカスタム クラスとしてバインドされるコレクションを返します。BindingList から派生した SortableBindingLazyList は、Sort Core メソッドを実装し、その内部リストを次のように保存します。リストの実体化を遅らせるクエリ。

于 2008-09-01T02:27:30.887 に答える
0

これは、データ バインディングを示す優れた「How Do I」ビデオです。

http://windowsclient.net/learn/video.aspx?v=52579

于 2008-08-27T07:46:48.897 に答える