苏州三木软件科技有限公司

 找回密码
 立即注册
搜索
热搜: 活动
查看: 1253|回复: 5

【求助】如何在全局表事件中添加右键菜单插入菜单事件

[复制链接]

21

主题

35

帖子

161

积分

注册会员

Rank: 2

积分
161
发表于 2023-6-14 11:34:50 | 显示全部楼层 |阅读模式


根据列名称在右键菜单中插入不同的菜单项,且在全局表事件中执行,这样每一个相同列的表都能够有相同的功能菜单。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

25

主题

313

帖子

2077

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2077
QQ
发表于 2023-6-14 13:04:51 | 显示全部楼层
概念
匿名方法:没有名字的方法,不需要名字的方法。
匿名方法是没有名称只有主体的方法。
匿名方法和委托搭载使用。
匿名方法 精确点可以改叫 匿名函数。
委托是用于引用与其具有相同标签的方法。换句话说,您可以使用委托对象调用可由委托引用的方法。
匿名方法(Anonymous methods) 提供了一种传递代码块作为委托参数的技术。
在匿名方法中您不需要指定返回类型,它是从方法主体内的 return 语句推断的。
使用场景
1. delegate 委托匿名方法

C#
//委托delegate int CalcuteSum(int num1,int num2);static void ObjectTest1(){    //委托匿名方法1    CalcuteSum calcuate1 = delegate (int num1, int num2)    {        return num1 + num2;    };    int result = calcuate1(1, 2);    Console.WriteLine(result);//3    //委托匿名方法1    calcuate1 = delegate (int num1, int num2)    {        return num1 + num2 + 1;    };    int result2 = calcuate1(1, 2);    Console.WriteLine(result2);//4    //委托静态方法    calcuate1 = TestSum;    int result3 = TestSum(1, 2);    Console.WriteLine(result3);//5}static int TestSum(int num1, int num2){    return num1 + 1 + num2 + 1;}

2. 匿名方法 和  Lamda表达式
   从 C# 3 开始,lambda 表达式提供了一种更简洁和富有表现力的方式来创建匿名函数。 使用 => 运算符构造 lambda 表达式:
< /TABLE >
3.方便开发和使用的委托  Action,Func

Action: 没有返回类型的委托定义。

C#
Func<int, int, int> sum = (a, b) => a + b;Console.WriteLine(sum(3, 4));  // output: 7
C#
Action greet = delegate { Console.WriteLine("Hello!"); };greet();Action<int, int> getNum = delegate (int num1, int num2){    var result = num1 * num2;     Console.WriteLine(result);};

Func :需要返回类型的委托定义。

C#
Func<int, int, int> sum = static delegate (int a, int b) { return a + b; };Console.WriteLine(sum(10, 4));  // output: 14

我们为什么需要学习这个匿名方法呢?因为我们在写全局表事件、全局项目事件、内部函数时,如果我们需要动态绑定一些控件的事件的话,就不像窗体事件以及表事件中那么方便了。这些事件代码只有一个方法体,我们想要绑定事件的话只有两种方法,一种是匿名方法,另外一种就是将控件的事件写到全局代码里面,然后再引用。
下面我们就以表事件BeforeShowContextMenu中的示例,将之转化,改写到全局表事件中,看看应该如何修改。
全局代码,因为Vb.net不支持匿名绑定事件,就只能在全局代码中写入菜单的单击事件代码了。注意:Vb.net在全局代码中创建一个MainModule的Module,而不是普通的Class。主要是为了方便在其他地方直接引用。

  1. Namespace UserClass
  2.     Public Module MainModule
  3.         Public Sub menuCommand_Click(ByVal senderSub As System.Object, ByVal eSub As C1.Win.C1Command.ClickEventArgs)
  4.              Dim cmdSub As SmCommand = CType(senderSub, SmCommand)
  5.              Dim lnkSub As sanMuSoft.CS.WinForm.Controls.SmCommandLink = CType(eSub.CallerLink, sanMuSoft.CS.WinForm.Controls.SmCommandLink)
  6.              MessageBox.Show(String.Format("当前菜单命令的文本为:{0},当前命令的名称为:{1}", lnkSub.Text, cmdSub.Name))
  7.         End Sub
  8.     End Module
  9. End Namespace
复制代码
  1. '获得对表的引用
  2. Dim tblMain As BaseGrid=sender
  3. Select Case e.HitType
  4.     Case HitTestTypeEnum.RowHeader
  5.         e.ContextMenu = Proj.GridContextMenu("选择区域右键菜单")
  6.         Exit Select
  7.     Case HitTestTypeEnum.ColumnHeader
  8.         '判断
  9.         If Proj.FormTags.ExtendedProperties(tblMain.Form.Name,tblMain.Name).ContainsKey("m_haveAddColumnMenu")=False OrElse Proj.FormTags.ExtendedProperties(tblMain.Form.Name,tblMain.Name)("m_haveAddColumnMenu") = False Then
  10.             Dim lnk As SmCommandLink = New SmCommandLink()
  11.             lnk.Name = "lnkTestMenu"
  12.             lnk.Text = "插入右键菜单"
  13.             lnk.Delimiter = True
  14.             lnk.ToolTipText = "这是插入右键菜单的提示信息"
  15.             Dim cmd As SmCommand = New SmCommand()
  16.             cmd.Name = "cmdTestMenu"
  17.             cmd.Text = "插入右键菜单"
  18.             cmd.ToolTipText = "命令中设置的ToolTipText"
  19.             cmd.Image = Sys.GetImage("accept_16x16.png", Path.Combine(Proj.ApplicationPath, "Images"))
  20.             '绑定全局代码中菜单的Click事件
  21.             AddHandler cmd.Click,AddressOf UserClass.MainModule.menuCommand_Click
  22.             lnk.Command = cmd
  23.             e.ContextMenu.CommandLinks.Add(lnk)
  24.             Proj.FormTags.ExtendedProperties(tblMain.Form.Name,tblMain.Name)("m_haveAddColumnMenu") = True
  25.         End If
  26.         Exit Select
  27.     Case Else
  28.         e.Cancel = True
  29.         Exit Select
  30. End Select
复制代码
  1. BaseGrid tblMain=sender as BaseGrid;
  2. switch (e.HitType)
  3. {
  4.     case HitTestTypeEnum.RowHeader:
  5.     {
  6.         // 如果是行标题,直接用自定义菜单代替
  7.         e.ContextMenu = Proj.GridContextMenu["选择区域右键菜单"];
  8.         break;
  9.     }
  10.    
  11.     case HitTestTypeEnum.ColumnHeader:
  12.     {
  13.         // 这里可以单独地添加一个或多个自定义菜单
  14.         if (Proj.FormTags.ExtendedProperties(tblMain.Form.Name,tblMain.Name)["m_haveAddColumnMenu"].CType<bool>(false) == false) //如果没有添加过菜单就添加,添加过了就不再重复添加了
  15.         {
  16.             SmCommandLink lnk = new SmCommandLink();
  17.             lnk.Name = "lnkTestMenu";
  18.             // 命令菜单上显示的文本
  19.             lnk.Text = "插入右键菜单";
  20.             // 是否显示分隔符
  21.             lnk.Delimiter = true;
  22.             // 鼠标移动到此菜单上时会提示出来的信息
  23.             lnk.ToolTipText = "这是插入右键菜单的提示信息";
  24.             SmCommand cmd = new SmCommand();
  25.             cmd.Name = "cmdTestMenu";
  26.             cmd.Text = "插入右键菜单";
  27.             cmd.ToolTipText = "命令中设置的ToolTipText";
  28.             // 设置命令的图标
  29.             cmd.Image = Sys.GetImage("accept_16x16.png", Path.Combine(Proj.ApplicationPath, "Images"));
  30.             // 绑定命令的单击事件
  31.             cmd.Click += (System.Object senderSub, C1.Win.C1Command.ClickEventArgs eSub)=>
  32.             {
  33.                 // 获得对命令的引用
  34.                 SmCommand cmdSub = (SmCommand)senderSub;
  35.                 // 获得对SmCommandLink的引用
  36.                 sanMuSoft.CS.WinForm.Controls.SmCommandLink lnkSub = (sanMuSoft.CS.WinForm.Controls.SmCommandLink)eSub.CallerLink;
  37.                 MessageBox.Show(string.Format("当前菜单命令的文本为:{0},当前命令的名称为:{1}", lnkSub.Text, cmdSub.Name));
  38.             };
  39.             // 将命令引用到菜单链接里面
  40.             lnk.Command = cmd;
  41.             // 将菜单链接添加到系统默认菜单里面
  42.             e.ContextMenu.CommandLinks.Add(lnk);
  43.             Proj.FormTags.ExtendedProperties(tblMain.Form.Name,tblMain.Name)["m_haveAddColumnMenu"] = true;
  44.         }
  45.         
  46.         break;
  47.     }
  48.    
  49.     default:
  50.     {
  51.         // 如果是其他部位的右键菜单,一律禁用
  52.         e.Cancel = true;
  53.         break;
  54.     }
  55. }
复制代码


上面的代码转换涉及到两个主要的知识点。
1、逻辑类型私有字段m_haveAddColumnMenu的转换。
因为在常规的表事件或者在窗体事件中,我们设置的私有字段的生效范围只有那一个窗体或者一个表中可访问。然后我们现在将代码转换到全局表事件当中时,作判断的话就必须将变量的维度拉到指定窗体、指定表对应的m_haveAddColumnMenu变量上,要不然就简单的设置一个Var变量的话,就会导致所有表事件只有第一个表触发时会执行此代码,然后其他表都因为这个变量而无法继续执行。
所以我们使用Proj.FormTags.ExtendedProperties这种支持三维的变量(详细介绍可参考:如何传递共享变量)的方法。
2、匿名方法的使用。
我们在使用匿名方法时,输入参数中的参数名不能与主方法中的e参数重名,需要进行改名称。由于匿名函数是允许直接访问事件中定义的局部变量的,所以在匿名函数里面使用的变量也要避免与局部变量重名。
回复

使用道具 举报

21

主题

35

帖子

161

积分

注册会员

Rank: 2

积分
161
 楼主| 发表于 2023-6-16 08:15:46 | 显示全部楼层
cmd.Click += Function(ByVal senderSub As System.Object, ByVal eSub As C1.Win.C1Command.ClickEventArgs) 这句不行
---------------------------

---------------------------
编译发生错误:

第1个错误发生于第83行:“Public Event Click(sender As Object, e As C1.Win.C1Command.ClickEventArgs)”是事件,不能直接调用。请使用“RaiseEvent”语句引发事件。;错误代码:【位于第83行



00063  Public Sub BeforeShowContextMenu(sender As Object,e As  sanMuSoft.CS.WinForm.BeforeShowContextMenuEventArgs)

00064  '获得对表的引用

00065  Dim tblMain As BaseGrid=sender

00066  Select Case e.HitType

00067  Case HitTestTypeEnum.RowHeader

00068  e.ContextMenu = Proj.GridContextMenu("选择区域右键菜单")

00069  Exit Select

00070  Case HitTestTypeEnum.ColumnHeader

00071  '判断

00072  If Proj.FormTags.ExtendedProperties(tblMain.Form.Name,tblMain.Name).ContainsKey("m_haveAddColumnMenu")=False OrElse Proj.FormTags.ExtendedProperties(tblMain.Form.Name,tblMain.Name)("m_haveAddColumnMenu") = False Then

00073  Dim lnk As SmCommandLink = New SmCommandLink()

00074  lnk.Name = "lnkTestMenu"

00075  lnk.Text = "插入右键菜单"

00076  lnk.Delimiter = True

00077  lnk.ToolTipText = "这是插入右键菜单的提示信息"

00078  Dim cmd As SmCommand = New SmCommand()

00079  cmd.Name = "cmdTestMenu"

00080  cmd.Text = "插入右键菜单"

00081  cmd.ToolTipText = "命令中设置的ToolTipText"

00082  cmd.Image = Sys.GetImage("accept_16x16.png", Path.Combine(Proj.ApplicationPath, "Images"))

00083  cmd.Click += Function(ByVal senderSub As System.Object, ByVal eSub As C1.Win.C1Command.ClickEventArgs)

00084  Dim cmdSub As SmCommand = CType(senderSub, SmCommand)

00085  Dim lnkSub As sanMuSoft.CS.WinForm.Controls.SmCommandLink = CType(eSub.CallerLink, sanMuSoft.CS.WinForm.Controls.SmCommandLink)

00086  MessageBox.Show(String.Format("当前菜单命令的文本为:{0},当前命令的名称为:{1}", lnkSub.Text, cmdSub.Name))

00087  End Function

00088  

00089  lnk.Command = cmd

00090  e.ContextMenu.CommandLinks.Add(lnk)

00091  Proj.FormTags.ExtendedProperties(tblMain.Form.Name,tblMain.Name)("m_haveAddColumnMenu") = True

00092  End If

00093  

00094  Exit Select

00095  Case Else

00096  e.Cancel = True

00097  Exit Select

00098  End Select

00099  

00100  

00101  End Sub

00102  End Class




---------------------------
确定   
---------------------------
回复

使用道具 举报

25

主题

313

帖子

2077

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2077
QQ
发表于 2023-6-16 10:04:51 | 显示全部楼层
因为Vb.net不支持匿名函数绑定事件,所以我改了一下上面的回复。你重新试试吧。
回复

使用道具 举报

21

主题

35

帖子

161

积分

注册会员

Rank: 2

积分
161
 楼主| 发表于 2023-6-16 11:01:24 | 显示全部楼层
表属性中的全局表事件没有BeforeShowContextMenu
回复

使用道具 举报

25

主题

313

帖子

2077

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2077
QQ
发表于 2023-6-16 14:04:17 | 显示全部楼层
等下个版本吧。或者自己先到数据库自己先添加一下。SysMTBaseGlobalEvents
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|苏州三木软件科技有限公司 ( 苏ICP备2022038390号 )

苏公网安备 32058502010732号

GMT+8, 2024-10-2 23:30 , Processed in 0.059578 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表