100165633.htm
来自「C#高级编程(第三版),顶死你们。。 。up」· HTM 代码 · 共 321 行 · 第 1/4 页
HTM
321 行
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> ContextMenu menu = new ContextMenu();</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // Now loop through those members and generate the popup menu</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // Note the cast to MethodInfo in the foreach</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> foreach (MethodInfo meth in members)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> {</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // Get the caption for the operation from the </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // ContextMenuAttribute</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> ContextMenuAttribute[] ctx = (ContextMenuAttribute[])</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> meth.GetCustomAttributes(typeof(ContextMenuAttribute), true);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> MenuCommand callback = new MenuCommand(this, meth);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> MenuItem item = new MenuItem(ctx[0].Caption, new </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> EventHandler(callback.Execute));</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> item.DefaultItem = ctx[0].Default;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> menu.MenuItems.Add(item);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> }</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> System.Drawing.Point pt = new System.Drawing.Point(x,y);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> menu.Show(parent, pt);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> }</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> }</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> private bool Filter(MemberInfo member, object criteria)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> {</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> bool bInclude = false;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // Cast MemberInfo to MethodInfo</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> MethodInfo meth = member as MethodInfo;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> if (meth != null)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> if (meth.ReturnType == typeof(void))</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> {</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> ParameterInfo[] parms = meth.GetParameters();</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> if (parms.Length == 0)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> {</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // Lastly check if there is a ContextMenuAttribute on the </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // method...</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> object[] atts = meth.GetCustomAttributes </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> (typeof(ContextMenuAttribute), true);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> bInclude = (atts.Length == 1);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> }</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> }</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> return bInclude;</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> }</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">}</span></p>
<p class="MsoNormal"><span lang="EN-US">ContextDataRow</span><span style="FONT-FAMILY: 宋体">类派生于</span><span lang="EN-US">DataRow</span><span style="FONT-FAMILY: 宋体">,且该类只包含两个成员函数。第一个函数</span><span lang="EN-US">PopupMenu</span><span style="FONT-FAMILY: 宋体">使用反射来查找对应于特定签名的方法,它还给用户显示这些选项的一个弹出菜单。第二个函数</span><span lang="EN-US">Filter()</span><span style="FONT-FAMILY: 宋体">在枚举方法时由</span><span lang="EN-US">PopupMenu</span><span style="FONT-FAMILY: 宋体">用作一个委托。如果成员函数符合相应的调用约定,它就只返回</span><span lang="EN-US">true</span><span style="FONT-FAMILY: 宋体">。</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US"> MemberInfo[] members = this.GetType().FindMembers(MemberTypes.Method,</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> BindingFlags.Public | BindingFlags.Instance,</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> new System.Reflection.MemberFilter(Filter),</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US"> null);</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">这个语句用于过滤当前对象上的所有方法,仅返回与下述条件相匹配的方法:</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; FTEL: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'"> </span></span><span style="FONT-FAMILY: 宋体">成员必须是一个方法</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; FTEL: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'"> </span></span><span style="FONT-FAMILY: 宋体">成员必须是一个公共实例方法</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; FTEL: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'"> </span></span><span style="FONT-FAMILY: 宋体">成员必须没有返回值</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; FTEL: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'"> </span></span><span style="FONT-FAMILY: 宋体">成员必须不带参数</span></p>
<p class="1" style="MARGIN-LEFT: 37.55pt; FTEL: -16.1pt"><span lang="EN-US">●<span style="FONT: 7pt 'Times New Roman'"> </span></span><span style="FONT-FAMILY: 宋体">成员必须包含</span><span lang="EN-US">ContextMenuAttribute</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">最后一个条件是一个定制属性,是专门为这个示例编写的。在完成</span><span lang="EN-US">PopupMenu</span><span style="FONT-FAMILY: 宋体">方法的分析后讨论这个定制属性:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">ContextMenu menu = new ContextMenu();</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">foreach (MethodInfo meth in members)</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">{</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> // ... Add the menu item</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">}</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">System.Drawing.Point pt = new System.Drawing.Point(x,y);</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 5.35pt; FTEL: 18.45pt"><span lang="EN-US">menu.Show(parent, pt);</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">创建一个上下文菜单实例,为每个满足上述条件的方法添加一个弹出菜单选项。接着,显示该菜单,如图</span><span lang="EN-US">22-29</span><span style="FONT-FAMILY: 宋体">所示。</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">这个示例中的主要困难是下面这段代码,在弹出的菜单中,每个要显示的成员函数都要重复一次该段代码:</span></p>
<p class="2" style="MARGIN-TOP: 8.15pt; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">System.Type ctxtype = typeof(ContextMenuAttribute);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">ContextMenuAttribute[] ctx = (ContextMenuAttribute[]) </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> meth.GetCustomAttributes(ctxtype, true);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">MenuCommand callback = new MenuCommand(this, meth);</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">MenuItem item = new MenuItem(ctx[0].Caption, </span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US"> new EventHandler(callback.Execute));</span></p>
<p class="2" style="MARGIN-LEFT: 21.45pt; FTEL: 18.45pt"><span lang="EN-US">item.DefaultItem = ctx[0].Default;</span></p>
<p class="2" style="MARGIN-TOP: 0cm; MARGIN-LEFT: 21.45pt; MARGIN-RIGHT: 0cm; FTEL: 18.45pt"><span lang="EN-US">menu.MenuItems.Add(item);</span></p>
<p align="center"><span lang="EN-US"><img height="193" src="22/image029.jpg" width="320" alt="" /></span></p>
<p style="FTEL: 8.15pt" align="center"><span style="FONT-FAMILY: 宋体">图</span><span lang="EN-US"> 22-29</span></p>
<p class="MsoNormal"><span style="FONT-FAMILY: 宋体">在上下文菜单中显示的每个方法都有一个</span><span lang="EN-US">ContextMenuAttribute</span><span style="FONT-FAMILY: 宋体">属性,它为菜单选项定义了一个友好的名称,因为</span><span lang="EN-US">C#</span><span style="FONT-FAMILY: 宋体">方法名不能有空格,在弹出菜单中使用英语要比使用某些内部代码更好。该属性从方法中获取,创建一个新菜单项,并把它添加到弹出式菜单的菜单项集合中。</span></p>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?