• 玩转控件:对Dev中GridControl控件的封装和扩展


        又是一年清明节至,细雨绵绵犹如泪光,树叶随风摆动....

            转眼间,一年又过去了三分之一,疫情的严峻让不少企业就跟清明时节的树叶一样,摇摇欲坠。裁员的裁员,降薪的降薪,996的996~~说起来都是泪,以上种种竟然在本公司都能见到,然而你现在还能看到博主翘着二郎腿,在工位上信誓旦旦的敲着代码也是奇迹!哎,生活不易,且行且珍惜吧!

      Talk is Cheap, Show me the code!

      如上所说,虽环境如此严峻,但也不能生疏了咱吃饭的手艺。不禁让我感受到,对技术的追求,不仅仅靠的是兴趣,更重要的是坚持啊!

      废话少说,前面几个环节,博主分享了对基础控件的封装和扩展(举了几个栗子,大家可以举一反三。或者公众号Call我,源码免费奉上。),后面和大家一起看看对容器控件的封装和扩展,本篇以常用的Dev中GridControl控件的封装和扩展。

      对容器控件的封装和扩展,和其他控件一样。首先,新建一个自定义类,让其继承Dev的GridControl:

     public class KzxGridControl : GridControl, IControl

        其次,给需要扩展的属性用特性方式标识,便于在VS设计界面来控制。本篇以最常用的两个功能来进行解析——GridControl右键菜单之复制行和导出Excel.具体核心代码如下:

    private bool _displayRightClickCopyMenu = true;
    private bool _displayRightClickExportExcel = true;
    /// <summary>
    /// 是否显示右键菜单的复制行
    /// </summary>
    [Category("右键菜单"), Description("DisplayRightClickMenu,显示右键菜单的复制行按钮"), Browsable(true)]
    public bool DisplayRightClickMenu
    {
        get { return _displayRightClickCopyMenu; }
        set { _displayRightClickCopyMenu = value; }
    }
    /// <summary>
    /// 是否显示右键菜单的导出Excel
    /// </summary>
    [Category("右键菜单"), Description("DisplayRightExportExcel,显示右键菜单的导出Excel按钮"), Browsable(true)]
    public bool DisplayRightExportExcel
    {
        get { return _displayRightClickExportExcel; }
        set { _displayRightClickExportExcel = value; }
    }

       编译后,返回设计界面,点击GridControl控件查看属性窗体会发现我们刚刚新增的扩展属性:

       属性设置完毕后,接下来就是初始化绑定该菜单的功能事件。

    /// <summary>
    /// 构造
    /// </summary>
    public KzxGridControl()
        : base()
    {
        if (this.MainView == null)
        {
            this.gridView1 = new DevExpress.XtraGrid.Views.Grid.GridView();
            ((System.ComponentModel.ISupportInitialize)(this.gridView1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
            this.SuspendLayout();
            this.gridView1.GridControl = this;
            this.gridView1.Name = "gridView1";
            this.gridView1.VertScrollVisibility = ScrollVisibility.Always;
            this.gridView1.HorzScrollVisibility = ScrollVisibility.Always;
            this.MainView = this.gridView1;
            this.ViewCollection.AddRange(new DevExpress.XtraGrid.Views.Base.BaseView[] {
        this.gridView1});
            ((System.ComponentModel.ISupportInitialize)(this.gridView1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this)).EndInit();
            this.ResumeLayout(false);
        }
    
        this._KzxBandedGridView = new KzxBandedGridView(false, _bandedGridView, this);
        this.Load += new EventHandler(GridControl_Load);
    }

      构造函数中,绑定load事件,用于触发菜单事件

            
    private void GridControl_Load(object sender, EventArgs e)
    { 
        ToolStripItem item3;
        ToolStripItem item4; 
    
        if (this.ContextMenuStrip == null)
        {
            this.ContextMenuStrip = new ContextMenuStrip();
        }
        this._ContextMenuStrip = this.ContextMenuStrip;
        _ContextMenuStrip.Opened += _ContextMenuStrip_Opened;
        //如果需要显示右键复制行
        if (_displayRightClickCopyMenu)
        {
            item3 = this._ContextMenuStrip.Items.Add(GetLanguage("RMI000452", "复制行"));//复制行
            item3.Name = "copyline";
            item3.Click += new EventHandler(CopyLine);
        }
        //如果需要显示右键导出Excel
        if (_displayRightClickExportExcel)
        {
            item4 = this._ContextMenuStrip.Items.Add(GetLanguage("SYS001196", "导出EXCEL"));//导出EXCEL
            item4.Click += new EventHandler((s, ee) =>
            { 
                //TODO:导出Excel动作
            });
        }
        ...

      导出方法比比皆是,因项目而异,多表头的,普通的。。就不献丑了(如有需要也可公众号call我,源码免费奉上)。此处我们拿复制行来举栗子,方法如下:

    #region 复制行 
      public void CopyLine(object sender, EventArgs e)
      {
          StringBuilder sqlsb = new StringBuilder();
          GridView gridview = this.MainView as GridView;
          DataTable dt = null;
          DataColumn[] columns = null;
          //BindingSource bs = null;
          DataRow row = null;
          DataRow rowtemp = null;
          //举例是拿DataTable做数据源,所以下面代码暂时屏蔽
          //bs = (this.DataSource as BindingSource);
          if (this.DataSource != null)
          {
              if (gridview.FocusedRowHandle >= 0)
              {
                  row = gridview.GetDataRow(gridview.FocusedRowHandle);
                  dt = ((this.DataSource as DataTable).DefaultView as DataView).Table;
                  if (dt.PrimaryKey != null)
                  {
                      columns = dt.PrimaryKey;
                  }
    
                  DataTable dttemp = dt.Clone();
                  rowtemp = dttemp.Rows.Add(row.ItemArray);
                  foreach (DataColumn c in columns)
                  {
                      rowtemp[c.ColumnName] = Guid.NewGuid();
                  }
                  //判断iOrder是否存在,存在则不复制,且取最大值+1
                  if (dt.Columns.Contains("iOrder"))
                  {
                      int maxIOrder = string.IsNullOrWhiteSpace(dt.Compute("max(iOrder)", "1=1").ToString()) ? 0 : Convert.ToInt32(dt.Compute("max(iOrder)", "1=1").ToString());
                      rowtemp["iOrder"] = maxIOrder + 1;
                  }
                  dt.ImportRow(rowtemp);
    
                  //执行右键复制行委托
                  OnRowCopy?.Invoke();
              }
          }
          else
          {
              KzxMessageBox.Show(sysClass.ssLoadMsgOrDefault("MSG002204", "数据源不能为空"));
          }
      }
      #endregion
    private void CopyLineMenu()
      {
          //是否显示右键的复制行按钮
          if (this._displayRightClickCopyMenu == true)
          {
              bool iscontain = false;
              ToolStripItem item3;
              if (this.ContextMenuStrip == null)
              {
                  this.ContextMenuStrip = new ContextMenuStrip();
              }
              this._ContextMenuStrip = this.ContextMenuStrip;
              for (int i = 0; i < this._ContextMenuStrip.Items.Count; i++)
              {
                  if (this._ContextMenuStrip.Items[i].Name.Equals("copyline", StringComparison.OrdinalIgnoreCase) == true)
                  {
                      iscontain = true;
                      break;
                  }
              }
              if (iscontain == false)
              {
                  item3 = this._ContextMenuStrip.Items.Add(GetLanguage("RMI000452", "复制行"));//复制行
                  item3.Name = "copyline";
                  item3.Click += new EventHandler(CopyLine);
              }
          }
      }

      具体效果如下:

       完成!不过注意,以上功能如果运用于实际项目,烦请做好控制,尤其复制行功能,初衷是一个很复杂的GridControl十几二十多列的,不想一列一列输入的,可以采用这种模式,复制行后改动下即可。注意最好是在编辑状态下显示此操作,否则不仅不会保存到数据库,还白费功夫!此本只是演示效果而已!本篇到此结束...

            最后,由于后续所有重写/重绘控件都在同一个项目使用,而且Dev系统引用文件较多,压缩后源码文件仍然很大,如果有需要源码的朋友,可以微信公众号联系博主,源码可以免费赠予~!有疑问的也可以CALL我一起探讨。

      最最后,感谢您的耐心陪伴!如果觉得本篇博文对您或者身边朋友有帮助的,麻烦点个关注!赠人玫瑰,手留余香,您的支持就是我写作最大的动力,感谢您的关注,期待和您一起探讨!再会!

  • 相关阅读:
    抓包工具之Charles
    docker之服务搭建
    Linux之查看开放端口
    Centos7下的开机自启动
    phpredis和predis
    Redis迁移工具之Redis-shake
    服务器间文件实时双向同步(rsync+inotify)
    Linux之轨迹记录(script)
    Redis集群之常用操作
    Redis集群搭建-多服务器
  • 原文地址:https://www.cnblogs.com/axing/p/12616181.html
Copyright © 2020-2023  润新知