zoukankan      html  css  js  c++  java
  • winform程序窗体相关设置

    在winform程序设计中经常会遇到一些设置性问题,在此记录总结一些经常遇到的小问题。

    1.MDI多窗体程序中,子窗口点击最大化,会出现看到子窗口的icon显示在菜单中,而实际上正常状态下子窗口的showIcon属性是false的。但最大化之后就是出显示在父窗口的菜单栏上,默认icon看起来不太好看。 这情况怎么样出掉icon.就是子窗口最大化不是显示icon。

    做法:

     在父窗体的MenuStrip控件中添加一个ItemAdd事件

    menuStrip_ItemAdded事件中添加如下代码:

    View Code
    /// <summary>
            
    /// 子窗口最大化时去掉主窗体菜单的icon图标
            
    /// 在mdi子窗体最大化的时候,会发生如下动作:
            /// 会在父窗体的MenuStrip上添加4个Item.
            
    /// 分别为Icon,最大化,恢复跟最小化。
            
    /// 其中除了Icon之外,其他三个的Text属性都赋予了文本值。
            
    /// 另外,Icon作为MenuStrip的第一项Item,它的索引为0.
            
    /// </summary>
            
    /// <param name="sender"></param>
            
    /// <param name="e"></param>
            private void menuStrip1_ItemAdded(object sender, ToolStripItemEventArgs e)
            {
                
    if (e.Item.Text == "")
                {
                    menuStrip1.Items.RemoveAt(
    0);
                }
            }

    OK 问题解决。

    2. 在winform程序中如果我们添加一个默认MDI窗体,那么会有一些默认菜单选项。实际当中很多菜单是不需要的,我们可以删除。

    如果我们添加一个单文档窗体,同时修改了isMdiContainer设置为ture,也能实现MDI窗体效果,如果这时候得自己添加菜单menuStrip然后逐个设置,添加系统默认MDI窗体还一些有功能菜单,比如窗口菜单,这个是比较通用的,基本上所有程序都可以用的。 自己添加单个文档窗口再修改成MDI窗体的这些功能就没有了。那么可以添加个别代码就可以实现相关功能。如有实现默认窗口菜单功能,除了水平平铺/垂直平铺/重叠.几个选项外,最主要一个功能还能根据一当前子窗口打开情况,显示成列表形式。

    其实只设置menuStrip一个属性MdiWindowListItem,指向窗口菜单项。 代码如下:

      this.menuStrip1.MdiWindowListItem = this.windowTSMI;

    OK,运行程序打开多个子窗口的时候就是排列出来了,且当前活动窗口就会在前面打勾。

    3. 多次打开子窗口只显示一次。

    一般情况下,打开子窗口多次我们代码如下:

    View Code
     /// <summary>
            
    /// 环境参数配置
            
    /// </summary>
            
    /// <param name="sender"></param>
            
    /// <param name="e"></param>
            private void EnvirnomentForm_Click(object sender, EventArgs e)
            {
                FrmEnvirnomentSet envie 
    = new FrmEnvirnomentSet();
                envie.MdiParent 
    = this;
                envie.Show();
            }

    那么重复点击多次菜单就会生成多个相同的窗口,因为每一次都是new 出来的。并不是运行同一个实例。

    View Code
        /// <summary>
            
    /// 通过窗口标题判断窗口是否存在,目的是为了只打开一次
            
    /// </summary>
            
    /// <param name="mdiFrm">包含多个子窗口的主窗口</param>
            
    /// <param name="caption">子窗口标题</param>
            
    /// <returns></returns>
            private static bool IsWinExist(Form mdiFrm, string caption)
            {
                
    bool isExist = false;
                
    foreach (Form frm in mdiFrm.MdiChildren)
                {
                    
    if (frm.Text.Equals(caption))
                    {
                        isExist 
    = true;
                        frm.Activate();
                        frm.Show();
                        
    break;
                    }
                }
                
    return isExist;
            }

            
    /// <summary>
            
    /// 环境参数配置
            
    /// </summary>
            
    /// <param name="sender"></param>
            
    /// <param name="e"></param>
            private void EnvirnomentForm_Click(object sender, EventArgs e)
            {
                
    string caption = otherQueryTSMI.Text;//用菜单名称
                if (!IsWinExist(this, caption))
                {
                    FrmEnvirnomentSet envie 
    = new FrmEnvirnomentSet();                          
                    envie.MdiParent 
    = this;
                    envie.Text 
    = caption;
                    envie.Show();
                }
            }

    这样通过判断标题Title的名称,很容易实现重复操作只打开一次窗口。当然也有其他很办法来实现这个功能,但我觉得这个最简单的办法。

     4.实现动态菜单功能

    有时程序需要动态菜单去配置,把菜单项写在数据库或者XML文件中,然后根据不同配置显示不同的菜单项

    我这里只是为了简单实现动态配置菜单功能,通过配置数据库相关字段来实现动态菜单

    做法如下:

    View Code
            /// <summary>
            
    /// 根据数据库仪器表创建动态菜单
             
    /// </summary>
            
    /// <param name="parent">ToolStripMenuItem根,如第一个菜单根名称为:CollectTSMI</param>
            private void CreateMenu(ToolStripMenuItem parent)
            {
               //操作数据库获取一个DataTable
                clsMachineOpr bll= new clsMachineOpr();
                DataTable dtbl 
    = bll.GetColumnDataTable(0"IsShow=True ORDER BY OrderId ASC""MachineName,MachineModel,IsSupport");
                
    if (dtbl != null && dtbl.Rows.Count > 0)
                {
                    htbl 
    = new Hashtable();
                    
    string code = string.Empty;
                    
    string text = string.Empty;
                    ToolStripMenuItem tsmi 
    = null;

                    
    //菜单部分
                    for (int i = 0; i < dtbl.Rows.Count; i++)
                    {
                        code 
    = dtbl.Rows[i]["MachineModel"].ToString().Trim();
                        text 
    = dtbl.Rows[i]["MachineName"].ToString().Trim();
                       // 加到hashtale中以备程序其他使用,这里不是必须的
                        htbl.Add(code, text);
                        if (Convert.ToBoolean(dtbl.Rows[i]["IsSupport"]))
                        {
                            defaultMethodTag 
    = code;
                        }
                        //可以添加前缀或者后缀,根据实际需要设置吧
                       
    //code = "Auto_" + code;
                        //text +="XXXXX";

                        tsmi 
    = new ToolStripMenuItem();
                        tsmi.Name 
    = code;
                        tsmi.Text 
    = text;
                        tsmi.Click 
    += new EventHandler(DynamicTSMI_Click);
                        parent.DropDownItems.Add(tsmi);
                    }
                    
    //加分隔符
                    ToolStripSeparator tStripSeparator1 = new ToolStripSeparator();
                    tStripSeparator1.Name 
    = "tStripSeparator1";
                    tStripSeparator1.Size 
    = new System.Drawing.Size(2176);
                    parent.DropDownItems.Add(tStripSeparator1);

                 }
                
    //如果还有其他固定的子菜单项,继续添加
                parent.DropDownItems.Add(otherDataHandTSMI);
            }

            
    /// <summary>
            
    /// 动态菜单事件,
            
    /// 采用反射技术。
            
    /// 注意:菜单click事件函数只能用public访问权限
            
    /// </summary>
            
    /// <param name="sender"></param>
            
    /// <param name="e"></param>
            private void DynamicTSMI_Click(object sender, EventArgs e)
            {  
                //如果是独立的外部类
                
    // MenuClickMethod menuClickMethod = new MenuClickMethod();
                
    //创建菜单调用方法类的实例,MenuClickMethod 的方法以子菜单名字命名,预先定义好每个
                
    //子菜单的操作,采用外部类的方法可以实现更加动态,接近插件形式进行封装.
                
    //但本次时间过紧,不考虑用外部类和插件形式实现。使用内部公有方法即可实现

                Type type 
    = this.GetType(); //menuClickMethod.GetType();如果用外部类采用注释的代码
                try
                {
                    
    //动态获取方法对象
                    MethodInfo mi = type.GetMethod(((ToolStripMenuItem)sender).Name);
                    mi.Invoke(
    thisnull);  //menuClickMethod  //如果用外部类调用,则用注解代码替换this。指定方法
                }
                
    catch (Exception ex)
                {
                    
    //  throw ex;
                    MessageBox.Show(ex.Message + ex.Source);
                }
            }

        
    //调用方法
           /// <summary>
           
    ///  这里菜单点击操作函数
           
    /// 函数名称要跟前面数据字段相同
            
    /// 且要设置成public
           
    /// </summary>
            public void XXXX()
            {
                
    //相当于点击菜单事件,操作你要实现的功能。。。。
            }

     5.限制程序只能打开一个,如果有应用正在运行,再次打开相同程序会给予用户提示

    做法如下:

    View Code
            /// <summary>
            
    /// 实现程序启动唯一实例的一种方法 
            
    /// </summary>
            private static void GetSingleThread()
            {
                
    string name = Process.GetCurrentProcess().ProcessName;
                
    int id = Process.GetCurrentProcess().Id;
                Process[] prc 
    = Process.GetProcesses();
                
    foreach (Process pr in prc)
                {
                    
    if ((name == pr.ProcessName) && (pr.Id != id))
                    {
                        MessageBox.Show(
    "对不起,本机已经有XXX统正在运行!\n.", caption, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        System.Environment.Exit(
    0);
                    }
                }
                
            }

     6.关闭窗口给予提示信息

    View Code
      /// <summary>
            
    /// 重写系统消息函数。
            
    /// 即在关闭系统时提示!
            
    /// </summary>
            
    /// <param name="msg">消息对象</param>
            protected override void WndProc(ref Message msg)
            {
                
    const int syscommand = 0x0112;
                
    const int close = 0xF060;
                
    if (msg.Msg == syscommand && ((int)msg.WParam == close))
                {
                    
    if (MessageBox.Show("程序正在运行,是否确定退出?""系统提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                    {
                        
    return;
                    }
                }
                
    base.WndProc(ref msg);
            }
  • 相关阅读:
    zufeoj NO.1(结构体简单题)
    用链表写插入排序
    用链表写插入排序
    POJ 3468 A Simple Problem with Integers(线段树)
    POJ 3468 A Simple Problem with Integers(线段树)
    HDU 3065 病毒侵袭持续中(AC自动机)
    HDU 3065 病毒侵袭持续中(AC自动机)
    ZOJ 3436 July Number(DFS)
    poj 3414 Pots(广搜BFS+路径输出)
    AOP技术应用和研究--AOP简单应用
  • 原文地址:https://www.cnblogs.com/cgli/p/2087953.html
Copyright © 2011-2022 走看看