Previous topicNext topic
Help > 开发指南 > 预备知识 >
表与数据

我们说的表基本就是指两类表,一个是可以直接绑定数据的SmGrid,还一个是必须有父子键的可编辑目录树表SmEditTreeGrid。他们在数据呈现上表现出一些不一样的东西。

我们在对表进行操作时,必须先要了解涉及数据的几个对象概念:DataTable、DataTableHelp、DataView、View、SmGrid、TableBindingSource

先来说说他们在数据处理过程中,各自承担的角色与作用。

SmGrid:这个就是我们实际看到的控件对象。我们可以通过Rows属性获得我们能看到的任何单元格的数据。也可以通过索引器来直接获得指定单元格数据:tbl(0,1)

 Vb.Net
Dim tbl As SmGrid=Proj.CurrentSmGrid
MsgBox(tbl.Rows(0)(1)) '返回“客户”。和tbl(0,1)返回的值一样
MsgBox(tbl.Rows(1)(1)) '返回“客户01 小计”。和tbl(1,1)返回的值一样
MsgBox(tbl.Rows(4)(1)) '返回“客户01”。和tbl(4,1)返回的值一样

 C#
SmGrid tbl = Proj.CurrentSmGrid;
MessageBox.Show(tbl.Rows[0][1].CType<string>("")); // 返回“客户”。和tbl[0,1]返回的值一样
MessageBox.Show(tbl.Rows[1][1].CType<string>("")); // 返回“客户01 小计”。和tbl[1,1]返回的值一样
MessageBox.Show(tbl.Rows[4][1].CType<string>("")); // 返回“客户01”。和tbl[4,1]返回的值一样

我们可以看到,如果我们想通过SmGrid来获取当前绑定的数据的话,其实是不经济的。因为我们要去判断当前行是不是标题?是不是目录树节点?是不是合计行?虽然我们可以通过tbl.Rows(4).DataIndex来判断当前是否绑定数据行,但是大多数情况下我们可以用View对象的tbl.View.ViewRows来访问当前表中显示的数据。表左侧的行标题显示的绑定数据在tbl.View.ViewRows中的顺序。

在实际使用过程中,我们更多地使用SmGrid对象作为一个控制的入口,因为通过它我们可以获得其他所有与之有关联的对象。我们可以做一些属性设置、做一些事件控制、做一些个性化定制。

DataTable:此对象即为System.Data.DataTable对象,我们从数据库中取出来的表数据就是存在这个对象中的。我们在表中所做的所有修改最终都会落实到此对象中。数据的最终保存也是通过它来实现的。理论上,我们对数据的操作都是对它的操作。但是,为了实现一些扩展功能,更方便我们进行数据操作,我们开发了另外一个类DataTableHelp。

DataTableHelp:DataTableHelp开发出来是为了替代DataTable进行数据操作的。我们也对DataTable进行了一系列的功能扩展。以方便我们更简单、高效地处理数据。

TableBindingSource:是数据源(DataTable)和控件(SmGrid)间的一座桥,可作为数据(其实是数据引用)的容器在不同窗体间传递,从而实现在弹出窗体中对数据的编辑。多窗体之间的表格副本也是通过绑定相同的TableBindingSource来实现的。此对象最大的作用就是让绑定相同数据源的控件、表、副表中显示的数据同步,显示相同的结果。

DataView:此对象即为System.Data.DataView对象,DataView是绑定的实质,正如其名,它是DataTable的数据的展现。因此可以对同一个DataTable,构建多个DataView,进而可以对这同样的数据实施不同的过滤、排序等方法,从不同侧面展示DataTable。TableBindingSource的实质也是控制的其中一个DataView。

View:主要是代码当前SmGrid中显示的数据有哪些。因为DataView中的数据不太方便读取,所以就有了View对象。在森之格平台里面,此对象不仅仅用来访问表当前显示的绑定数据,更多的还承担了记录表属性、列属性相关信息的功能 。

总结:当我们在表中删除一条数据,并设置了表的筛选SmGrid.View.Filter,那么我们会得到SmGrid.View.ViewRows.Count<SmGrid.Rows.Count<SmGrid.DataTableHelp.DataRows.Count<SmGrid.DataTableHelp.DataTable.Rows.Count,这是因为SmGrid的行包含标题所以>View的行数,因为筛选了数据,而View是筛选后的结果,DataTableHelp里面依然包含了所有数据(删除行除外),DataTable的数量大于DataTableHelp的原因是,DataTable中是包含已经删除的行的。

下面我们就再帮大家梳理一下上面几个对象的关系。先只讲SmGrid、DataView、DataTable之间的关系。我们从数据库中通过SQL语句加载过来的数据是保存在DataTable中的,而为了支持在前端表中可以支持筛选、排序等功能,这时候微软又引进了DataView这个对象。比如我用SQL从数据库中加载了下面这些数据保存到DataTable里面,如果我们对表进行筛选,只显示这些数据中产品等于“产品01”的数据,这时候我们就是通过DataView对象来控制显示到SmGrid中的数据的。而我们的DataTable里面并没有因为筛选条件而变动任何东西。

而再聊到SmGrid上来,在DataView提供的数据基础上,我们还可以做一些分组统计,在不影响DataView本身数据的基础上再做一些数据统计。像合计、数据合并都是不影响绑定数据的情况下,以更清晰、合理的方式展示绑定数据。我们看到的显示了行号的数据就是绑定的数据行,用代码判断一行数据是否绑定的话就是“tbl.Rows(4).DataIndex>=0”。在绑定行上操作修改数据的话会传导修改绑定的数据行。如果是修改非绑定行(在绑定模式下,这些行基本上都是标题或树节点)是不会影响绑定的数据的。

理解上面三组对象的关系,基本上就理解了数据表绑定的实质。如果我们想同一个数据源绑定多个数据表与控件的话,我们这时候就要引进 TableBindingSource这个对象了。由它负责将我们绑定的多个数据表与控件进行数据同步,达到修改一个地方,其他地方的数据也跟着同步改变。这时候,我们再了解一下,View是对DataView的扩展与替代,DataTableHelp是对DataTable的扩展与替换,则这些对象之间的关系就清晰明了了。

综上所述,我们日常操作数据时,一般通过View和DataTableHelp两个对象操作就可以了,在遇到一些与表面显示相关的场景时,可以考虑通过操作SmGrid来实现。