3

この問題は私を数年間悩ませてきました、そして多分ここの誰かが私が再びそれに遭遇したので簡単な解決策を知っています。

質問:新しい(異なる)データソースがグリッドに割り当てられる前に、XtraGridに現在フォーカスされている行インデックスを「忘れる」方法はありますか?

背景XtraGridは、マルチペインWinformの別のパネルに表示されるものの一種のコントローラーとして使用します。

ここで、XtraGridのデータソースがメニューの選択に応じて変化し続けるという架空のシナリオを想像してみてください。メニュー項目1は、カフェテリアの今日のプリモピアットのリスト(ID、名前)をグリッドに表示します。メニュー項目2は、ユーザーがその日に電話をかけなければならない顧客のリスト(ID、名前)をグリッドに表示します。重要なことは、これらは別個の別個のデータソースであり、グリッドのデータソースが割り当てられ、再割り当てされていることです。

この質問の重要な事実:グリッドのFocusedRowChangedイベントを 、コントローラーグリッドでユーザーの選択をトラップする単一の場所にする必要があります。私たちは「スパゲッティコードなし」のショップです。FocusedRowChangedは、キーボードナビゲーションも処理するため、クリックイベントよりも優れています。フォーカスのある行には、パネル#2に表示するためにデータベースからフェッチする必要のある詳細レコードのIDが含まれています。これは機能します-ほとんどの場合

動作しない方法は次のとおりです。特定の日に、ユーザーが連絡する必要のある顧客のリストに1行しか含まれていないとします。したがって、グリッドの最初の(そして唯一の)行はフォーカスされた行です。ここで、ユーザーがメニューに移動し、メニュー項目を選択してその日のカフェテリアのプリモピアットを表示するとします。ユーザーがEntreesリストの最初の項目をクリックしても、グリッドは前のデータソースからのフォーカスされた行インデックスのメモリを保持しているため、FocusedRowChangedイベントは発生しません。フォーカスされた行のインデックスは変更されていません。したがって、ユーザーの選択は何もトリガーしません。

DevExpressに2番目の行オブジェクト指向モード(行インデックス指向のアプローチとは異なる)を提供させようとしました。これにより、グリッド内の各行にGUIDがあり、FocusedRowChangedイベントは現在のGUIDが発生するたびに発生します。フォーカスされた行のインデックスがたまたま同じであったかどうかに関係なく、フォーカスされた行は以前にフォーカスされた行のGUIDとは異なりました。これにより、データソースの動的な変更が可能になり、目的の動作が可能になります。しかし、彼らは非難しました。

そこで、もう一度質問します。新しいデータソースがグリッドに割り当てられる前に、XtraGridに現在フォーカスされている行インデックスを「忘れる」方法はありますか?

4

4 に答える 4

3

ティム、グリッドに1行のデータしかなく、データソースを変更したときに、まったく同じ問題が発生しました。新しいデータソースを設定した後、gridview.FocusedRowHandle=-1を設定することで解決しました。

于 2011-05-12T21:35:02.883 に答える
1

同様の状況で、私は購読しています

FocusedRowObjectChanged

イベント(DevExpress 16.1を使用)。

于 2017-06-19T08:21:10.320 に答える
0

この問題の最善の解決策は、新しいGridViewオブジェクトを作成し、そのDoChangeFocusedRowInternalメソッドをオーバーライドすることだと思います。以下に、このメソッドのデフォルトの実装を示します。あなたがする必要があるのはあなたの必要が指示するのと同じようにマークされた行を変更することです。また、GridViewの子孫クラスを作成して設計時に使用するために登録する方法の記事を参照してください。これにはいくつかの有用な情報が含まれています。

public class MyGridView : GridView {
        protected override void DoChangeFocusedRowInternal(int newRowHandle, bool updateCurrentRow) {
            if(this.lockFocusedRowChange != 0) return;
            if(!IsValidRowHandle(newRowHandle))
                newRowHandle = DevExpress.Data.DataController.InvalidRow;
            if(FocusedRowHandle == newRowHandle) return; // <<<<<<
            int currentRowHandle = FocusedRowHandle;
            BeginLockFocusedRowChange();
            try {
                DoChangeFocusedRow(FocusedRowHandle, newRowHandle, updateCurrentRow);
            }
            finally {
                EndLockFocusedRowChange();
            }
            RaiseFocusedRowChanged(currentRowHandle, newRowHandle);
        }
    }

アップデート

私のコード:

namespace MyXtraGrid {

        public class MyGridControl : GridControl {
            protected override BaseView CreateDefaultView() {
                return CreateView("MyGridView");
            }
            protected override void RegisterAvailableViewsCore(InfoCollection collection) {
                base.RegisterAvailableViewsCore(collection);
                collection.Add(new MyGridViewInfoRegistrator());
            }
        }

        public class MyGridViewInfoRegistrator : GridInfoRegistrator {
            public override string ViewName { get { return "MyGridView"; } }
            public override BaseView CreateView(GridControl grid) {
                return new MyGridView(grid as GridControl);
            }
        }
        public class MyGridView : GridView {
            public MyGridView(GridControl ownerGrid) : base(ownerGrid) { }
            public MyGridView() { }


            protected virtual bool RowEqual(int focusedRowHandle, int newRowHandle) {
                if(IsDesignMode)
                    return focusedRowHandle == newRowHandle;
                DataRow row1 = GetDataRow(focusedRowHandle);
                DataRow row2 = GetDataRow(newRowHandle);
                return row1 == row2;
            }

            protected override void DoChangeFocusedRowInternal(int newRowHandle, bool updateCurrentRow) {
                if(this.lockFocusedRowChange != 0) return;
                if(!IsValidRowHandle(newRowHandle))
                    newRowHandle = DevExpress.Data.DataController.InvalidRow;
                if(RowEqual(FocusedRowHandle, newRowHandle))
                    return;
                int currentRowHandle = FocusedRowHandle;
                BeginLockFocusedRowChange();
                try {
                    DoChangeFocusedRow(FocusedRowHandle, newRowHandle, updateCurrentRow);
                }
                finally {
                    EndLockFocusedRowChange();
                }
                RaiseFocusedRowChanged(currentRowHandle, newRowHandle);
            }
        }
    }
于 2011-05-05T20:47:11.643 に答える
0

データソースが変更されたときに発生するDataSourceChangedイベントをサブスクライブできるため(ご想像のとおり)、GetFocusedObject()を使用してオブジェクトを取得し、他のグリッドに関連するアイテムを表示できます...

于 2011-11-04T14:57:16.750 に答える