为何DataNavigator与GridControl共享DataTable时可同步当前位置?
问题描述
我在实际项目中偶然发现一个奇怪的现象,无法解释其原因,特求助。
我用一个简单示例验证了该现象:创建DevExpress空白WinForms项目,在窗体上放置GridControl和DataNavigator,通过代码创建一个包含若干行的DataTable,并将该表同时赋值给两者的DataSource:
gridControl1.DataSource = table; dataNavigator1.DataSource = table;
注意,gridControl1与dataNavigator1之间无直接关联,且理论上DataTable并无“当前行”的概念。
但神奇的现象发生了:点击DataNavigator的任意控制按钮,Grid中的焦点行会随之变化;反之,点击Grid中的任意行,焦点行改变后,DataNavigator也会同步显示新位置。
gridControl1与dataNavigator1是如何知晓彼此的当前位置的?根据我的理解,两者仅共享无“当前位置”概念的DataTable,本不应同步当前行位置,我忽略了什么?
窗体后台代码如下:
public partial class Form1 : DevExpress.XtraEditors.XtraForm { private DataTable table; public Form1() { InitializeComponent(); Init(); } private void Init() { table = new DataTable(); table.Columns.Add("col1", typeof(int)); table.Columns.Add("col2", typeof(string)); DataRow row = table.NewRow(); row[0] = 10; row[1] = "first row"; table.Rows.Add(row); row = table.NewRow(); row[0] = 20; row[1] = "second row"; table.Rows.Add(row); row = table.NewRow(); row[0] = 30; row[1] = "third row"; table.Rows.Add(row); gridControl1.DataSource = table; dataNavigator1.DataSource = table; } }
窗体设计器中网格和导航器的声明如下:
private DevExpress.XtraEditors.DataNavigator dataNavigator1; private DevExpress.XtraGrid.GridControl gridControl1;
原因解析
- 核心在于WinForms的
BindingContext和CurrencyManager机制:当控件设置DataSource时,会通过窗体的BindingContext获取对应数据源的CurrencyManager实例。同一个DataTable在同一窗体的BindingContext下会共享同一个CurrencyManager。 CurrencyManager负责维护数据源的“当前项”(即你所说的“当前行”),它会监听数据源变化,同时向绑定控件通知当前项的变更。- DevExpress的
GridControl和DataNavigator均基于WinForms数据绑定机制实现:- 点击
DataNavigator按钮时,它会操作共享的CurrencyManager改变当前项位置,CurrencyManager触发事件通知GridControl,后者同步更新焦点行。 - 在
GridControl中点击行时,GridControl会更新CurrencyManager的当前项位置,DataNavigator监听该变化,同步更新自身导航状态。
- 点击
- 你之前的误区是忽略了WinForms数据绑定的底层逻辑:
DataTable本身无当前行,但绑定控件会通过CurrencyManager维护这个状态,且同一数据源在同一上下文下共享该管理器。
内容的提问来源于stack exchange,提问作者Vlad Gonchar
相关产品推荐
相关产品推荐

