Previous topicNext topic
Help > 开发指南 > 预备知识 >
如何引用表

我们平台在数据处理方面基本是围绕着表的。可以参考“SmGrid”,SmGrid已经将我们平台中主要的数据处理对象全部关联了。我们在代码编写过程中,如果可以正确引用到对应的表,那么就可以随意地操纵数据了。

我们在不同的地方引用表的方式不一样。下面我们就依次介绍不同地方引用表的方式。

1、表事件。无论是在全局表事件,还是在窗体表事件中,我们获得表的方式都是相同的,就是通过事件参数中的sender来进行转换获得。

VB语法:

Dim tbl As SmGrid=sender
C#语法:
SmGrid tbl=sender as SmGrid;
 
在窗体表事件中,我们需要定位到指定的事件中,然后在事件里面定义引用相应的表。同时还要注意,我们平台里面的表主要有两种:SmGrid和SmEditTreeGrid。请根据实际的表类型定义表变量。
 
 
2、在窗体事件中引用表。在窗体的表事件中引用表可以直接用上面的方法。如果是在窗体事件或窗体其他控件的事件中该如何引用表呢?
 主要有两种,一种就是直接定位表,通过窗体中的Grids集合访问到所有已经加载的表。因为只能访问到已加载的表,那么没有加载的时候自然就访问不到了。所以特别注意窗体Load、AfterLoad事件不能使用此方法。
另外一种就是按照控件名称引用,通过窗体中的ControlDictionary方法返回的控件字典来访问。
VB.Net
        Public Sub TestForm_Load(sender As Object,e As  System.EventArgs)
            '引用表,窗体事件中的窗体可以直接通过Me.SmForm来访问
            Dim tbl As SmGrid=Me.SmForm.ControlDictionary()("SmGrid1")
            
        End Sub
        
        Public Sub SmTextBox1_ValueChanged(sender As Object,e As  System.EventArgs)
            '通过窗体的Grids属性来访问已经加载的表
            Dim SmGrid1 As SmGrid=Me.SmForm.Grids("SmGrid1")
            
        End Sub
C#
public void TestForm_Load(object sender, System.EventArgs e)
{
    // 引用表,窗体事件中的窗体可以直接通过this.SmForm来访问
    SmGrid tbl = this.SmForm.ControlDictionary()["SmGrid1"] as SmGrid;
}

public void SmTextBox1_ValueChanged(object sender, System.EventArgs e)
{
    // 通过窗体的Grids属性来访问已经加载的表
    SmGrid SmGrid1 = this.SmForm.Grids["SmGrid1"] as SmGrid;
}
 
3、窗体菜单事件。我们在表属性设置窗口中,可以自由地定义绑定表的窗体菜单。这些窗体菜单一般都是绑定固定的表的。我们可以通过这个窗体菜单来获得对表的引用。
 
 VB.Net
'通过Proj.CurrentClickedCommandEventArgs静态属性获得当前按钮Click事件的参数
Dim e As sanMuSoft.CS.WinForm.CommandClickEventArgs= Proj.CurrentClickedCommandEventArgs
'可以通过e参数来获得菜单的命令链接C1CommandLink
e.CallerLink.Text="已审核"
'通过Proj.CurrentClickedGridMenu静态属性获得当前菜单
Dim menu As GridMenuBase= Proj.CurrentClickedGridMenu
'通过菜单绑定的表对象获得表引用,请根据实际的表类型定义变量
Dim tbl As SmGrid=menu.BaseGrid
Dim tblTree As SmEditTreeGrid=menu.BaseGrid
tbl.Save()

 C#
// 通过Proj.CurrentClickedCommandEventArgs静态属性获得当前按钮Click事件的参数
sanMuSoft.CS.WinForm.CommandClickEventArgs e = Proj.CurrentClickedCommandEventArgs;
// 可以通过e参数来获得菜单的命令链接C1CommandLink
e.CallerLink.Text = "已审核";
// 通过Proj.CurrentClickedGridMenu静态属性获得当前菜单
GridMenuBase menu = Proj.CurrentClickedGridMenu;
// 通过菜单绑定的表对象获得表引用,请根据实际的表类型定义变量
SmGrid tbl = menu.BaseGrid;
SmEditTreeGrid tblTree = menu.BaseGrid;
tbl.Save();

4、当前表。Proj.CurrentGrid全局属性返回的是当前表,这个返回的是一个BaseGrid类型,所以它既可能返回SmGrid对象,也可能返回SmEditTreeGrid对象。当我们点击任意一个表时,此时Proj.CurrentGrid就会指向此表对象。同时系统会触发项目事件里面的CurrentGridChanged事件。

我们在写代码的时候,为了访问到具体的SmGrid对象中的属性,如果直接使用Proj.CurrentGrid可能每次都要进行类型转换。所以我们同时提供了Proj.CurrentSmGrid属性,这样就不需要我们每次都进行类型转换了。但是,当我们的当前表是SmEditTreeGrid时,此时Proj.CurrentSmGrid返回的是空值(VB.Net中是Nothing,C#中是null)。

5、直接定位表。我们可以通过Proj.OpenedForms("打开窗体名").Grids("tblMain")这种方式直接定位到已经打开的某个窗口中的指定名称的表。这种定位方式一定要注意指定的窗体必须已经打开,对应的表也加载了数据。SmForm.Grids属性里面包含的都是已经加载了数据的表集合。在窗体的Load、AfterLoad事件不可以用此方法引用表,因为这时候窗体可能还没有打开并添加到OpenedForms集合中,表也还没有正式加载。

 VB.Net
 
Dim strFormName As String="窗体名"
Dim strTableName As String="tblMain"
'先判断一下指定的窗体是否打开,再判断一下指定的表是否加载。
'SmForm.Grids属性里面包含的都是已经加载了数据的表集合。
If Proj.OpenedForms.Contains(strFormName) AndAlso Proj.OpenedForms(strFormName).Grids.Contains(strTableName) Then
    '直接根据打开窗体定位表。
    Dim tbl As SmGrid=Proj.OpenedForms(strFormName).Grids(strTableName)
    tbl.Save()
End If

 

 C#
string strFormName = "窗体名";
string strTableName = "tblMain";
// 先判断一下指定的窗体是否打开,再判断一下指定的表是否加载。
// SmForm.Grids属性里面包含的都是已经加载了数据的表集合。
if (Proj.OpenedForms.Contains(strFormName) && Proj.OpenedForms[strFormName].Grids.Contains(strTableName))
{
    // 直接根据打开窗体定位表。
    SmGrid tbl = Proj.OpenedForms[strFormName].Grids[strTableName];
    tbl.Save();
}

6、引用父表。IDataRuleGrid接口中有Relation属性,通过Relation属性的ParentGrid属性可以访问到父表对象。正常情况下SmGrid和SmEditTreeGrid是实现了IDataRuleGrid接口的,可以直接访问父表。

 VB.Net
Dim tbl As SmGrid=Proj.CurrentSmGrid
'如果主表是SmGrid类型
Dim tblMain As SmGrid= tbl.Relation.ParentGrid
'如果主表是SmEditTreeGrid类型
Dim tblEditTree As SmEditTreeGrid=tbl.Relation.ParentGrid

C#
SmGrid tbl = Proj.CurrentSmGrid;
// 如果主表是SmGrid类型
SmGrid tblMain = tbl.Relation.ParentGrid as SmGrid;
// 如果主表是SmEditTreeGrid类型
SmEditTreeGrid tblEditTree = tbl.Relation.ParentGrid as SmEditTreeGrid;

7、引用子表。IDataRuleGrid接口中的Relation属性还有一个ChildrenGrids属性,可以访问到对应的所有子表。

 VB.Net
Dim tbl As SmGrid=Proj.CurrentSmGrid
'遍历当前表的所有子表
For Each tblSub As IDataRuleGrid In tbl.Relation.ChildrenGrids
    '模式一:遍历子表所能看到的数据集合
    For Each dr As RowData In tblSub.View.ViewRows
        
    Next
    '模式二:遍历子表所有数据集合
    For Each dr As RowData In tblSub.DataTableHelp.DataRows
        
    Next    
Next
'根据序号获取指定的子表
Dim tblSub01 As SmGrid=tbl.Relation.ChildrenGrids(0) '第一个子表
'根据子表名称来获取指定的子表
Dim tblSub02 As SmGrid=tbl.Relation.ChildrenGrids("tbl_vwEmployeeFamilyMember") 

C#
SmGrid tbl = Proj.CurrentSmGrid;
// 遍历当前表的所有子表
foreach (IDataRuleGrid tblSub in tbl.Relation.ChildrenGrids)
{
    // 模式一:遍历子表所能看到的数据集合
    foreach (RowData dr in tblSub.View.ViewRows)
    {
        
    }
    // 模式二:遍历子表所有数据集合
    foreach (RowData dr in tblSub.DataTableHelp.DataRows)
    {
        
    }
}
// 根据序号获取指定的子表
SmGrid tblSub01 = tbl.Relation.ChildrenGrids[0] as SmGrid; // 第一个子表
// 根据子表名称来获取指定的子表
SmGrid tblSub02 = tbl.Relation.ChildrenGrids["tbl_vwEmployeeFamilyMember"] as SmGrid; 

8、引用副表。什么是副表?我们知道,主窗口下面可以显示对应的子表,但是在弹出的子窗口中我们同样可以显示对应的子表。在观感上,下面的子表是双份的。我们修改了任何子表中的数据,另外的表中数据也会跟着同步更新显示。我们说,子窗口中的子表是主窗口中的子表的副表。他们都同时绑定的相同的TableBindingSource。

原则上,同一个源表,我们可以绑定到多个副表,绑定也非常简单,只需要SmGrid.SourceSmGrid=tblSource即可。

Vb.Net
Dim tbl As SmGrid=Proj.CurrentSmGrid
'如果当前表是副表
If tbl.IsCopyGrid Then '判断当前表是否副表
    '如果是副表,可以通过SourceSmGrid属性来获得对源表的引用
    Dim tblMain As SmGrid= tbl.SourceSmGrid
End If
'如果当前表有对应的副表
If tbl.CopyGrids.Count>0 Then
    '遍历所有副表
    For Each tb As BaseGrid In tbl.CopyGrids
        '结束编辑
        tb.EndEdit()
    Next
End If

C#
SmGrid tbl = Proj.CurrentSmGrid;
// 如果当前表是副表
if (tbl.IsCopyGrid) //判断当前表是否副表
{
    // 如果是副表,可以通过SourceSmGrid属性来获得对源表的引用
    SmGrid tblMain = tbl.SourceSmGrid;
}

// 如果当前表有对应的副表
if (tbl.CopyGrids.Count > 0)
{
    // 遍历所有副表
    foreach (BaseGrid tb in tbl.CopyGrids)
    {
        // 结束编辑
        tb.EndEdit();
    }
}