惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
腾讯CDC
D
Docker
G
Google Developers Blog
D
DataBreaches.Net
雷峰网
雷峰网
Blog — PlanetScale
Blog — PlanetScale
S
SegmentFault 最新的问题
The Cloudflare Blog
有赞技术团队
有赞技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Stack Overflow Blog
Stack Overflow Blog
大猫的无限游戏
大猫的无限游戏
量子位
美团技术团队
aimingoo的专栏
aimingoo的专栏
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Engineering at Meta
Engineering at Meta
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - 何以解忧唯有撸码

Winform上位机也能写出媲美Avalonia的界面 C# 视频录制监控系统 玩转控件:封装个带图片的Label控件 c#实现包裹扣面单的几种方式 c#造个轮子--GIF录制工具 c#造个轮子-取色器TakeColor(附源码) OpenCvSharp基于颜色反差规避FBA面单贴标2 OpenCvSharp基于颜色反差规避FBA面单贴标 winform 绘制太阳,地球,月球 运作规律 玩转控件:GDI+动态绘制流程图 玩转控件:Fucking ERP之流程图 玩转控件:对Dev的GridControl控件扩展 玩转控件:封装Dev的SearchLookupEdit 玩转控件:封装Dev的LabelControl和TextEdit 玩转控件:扩展Dev中SimpleButton 玩转控件:重写/重绘Dev中MessageBox弹窗控件 C# 视频监控系统(提供源码分享) C# 小游戏-拼图魔方【Game Puzzle】 玩转控件:重绘DEVEXPRESS中DateEdit控件 —— 让DateEdit支持只选择年月 (提供源码下载) 玩转控件:重绘ComboBox —— 让ComboBox多列显示 (提供源码下载) 分享:动态添加控件和公用章水印工具 提供源码下载
玩转控件:对Dev中GridControl控件的封装和扩展
何以解忧唯有撸码 · 2020-04-01 · via 博客园 - 何以解忧唯有撸码

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

        转眼间,一年又过去了三分之一,疫情的严峻让不少企业就跟清明时节的树叶一样,摇摇欲坠。裁员的裁员,降薪的降薪,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我一起探讨。

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