3

这个问题困扰了我好几年,也许这里有人知道一个简单的解决方案,因为我又遇到了。

问题:有没有办法让 XtraGrid 在将新的(不同的)数据源分配给网格之前“忘记”当前的焦点行索引?

背景 我们使用 XtraGrid 作为一种控制器,用于显示在多窗格 Winform 的另一个面板中的内容。

现在想象一个假设场景,其中 XtraGrid 的数据源根据菜单选择不断变化。菜单项 1 使用自助餐厅中今天的主菜列表填充网格:ID、名称。菜单项 2 使用用户当天必须致电的客户列表填充网格:ID、姓名。重要的是这些是独立的不同数据源,并且正在分配和重新分配网格的数据源。

这个问题的关键事实:我们希望网格的 FocusedRowChanged 事件成为 我们在控制器网格中捕获用户选择的唯一位置。我们是一家“没有意大利面条代码”的商店。FocusedRowChanged 比单击事件更好,因为它也处理键盘导航。具有焦点的行包含我们需要从数据库中获取以显示在面板 #2 中的详细记录的 ID。这行得通——大多数时候

这是它不起作用的原因:假设在给定的一天,用户必须联系的客户列表仅包含一行。所以网格中的第一(也是唯一)行是焦点行。现在假设用户进入菜单并选择菜单项以显示当天的自助餐厅主菜。当用户单击 Entrees 列表中的第一项时,FocusedRowChanged 事件不会触发,因为网格保留了来自前一个数据源的焦点行索引的内存。焦点行索引没有改变。因此用户的选择不会触发任何事情。

我试图让 DevExpress 提供第二种更面向行对象的模式(与面向行索引的方法不同),其中网格中的每一行都有一个 GUID,并且只要当前的 GUID 的 GUID 就会触发 FocusedRowChanged 事件聚焦行与先前聚焦行的 GUID 不同,无论聚焦行索引是否恰好相同。这将允许数据源的动态更改并启用所需的行为。但他们反对。

所以我会再次问我的问题,有没有办法让 XtraGrid 在将新数据源分配给网格之前“忘记”当前的焦点行索引?

4

4 回答 4

3

蒂姆,当网格中只有一行数据然后更改数据源时,我遇到了完全相同的问题。我在设置新数据源后通过设置 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

You can subscribe on the DataSourceChanged event which will fire when Data source changes (you guessed it!) so then you can get using GetFocusedObject() the object and display the relevant items for the other grid...

于 2011-11-04T14:57:16.750 回答