玩轉控件:對Dev的GridControl控件擴展


緣由

   一切實現來源於需求,目的在於不盲目造輪子,有小伙伴兒在看了《玩轉控件:對Dev中GridControl控件的封裝和擴展》文章后,私信作者說,因公司業務邏輯比較復雜,展示字段比較多,尤其網格列表控件展示數據太多時候,很多關鍵列信息不同用戶要求展示效果不同,問我有沒有好點的處理方式來滿足不同客戶的需求。

    看到這里作者還是比較暗自竊喜的,畢竟自己造的輪子不止作者一個人在用,而且還能收獲客戶的實際需求來完善輪子。當然客戶需求存在即合理。畢竟There are a thousand Hamlets in a thousand people's eyes.

何以解憂唯有擼碼

   有了需求,眼球一轉,就擼起袖子加油干吧。初步想法直接在《玩轉控件:對Dev中GridControl控件的封裝和擴展》的基礎上,右鍵菜單網格設置狀態里面處理吧。把處理后的結果通過配置文件方式(ini,xml...)存儲起來,網格加載的時候,通過校驗是否存在配置文件來加載不同客戶的配置信息即可。    有了想法,就行動起來吧!氣運丹田,雙手攤開,扎下馬步,使出"拖控件大法"一氣呵成!

   大致需求與實現如上圖,本來還有列中文列名的,但是客戶說不要~~(如有更多不同需求或更好的想法,請自行添加或者公眾號私信作者一起探討)

Talk is Cheap,Show me the Code

  跟用戶反復溝通,具體效果圖如上,下面一起看看是如何實現的。

    思路:網格表格右鍵點擊網格狀態設置,彈出如上設置窗體,窗體界面加載的時候綁定GridControl所有數據列,並在保存時候存儲到配置文件中,具體代碼如下:

 /// <summary>
  /// 數據加載初始化
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  private void frm_GridSetting_Load(object sender, EventArgs e)
  {
      //讀取配置文件,更新網格狀態
      string sPath = $@"{ Application.StartupPath}\Task.xml";
      DataTable dtColumns = this.gc.DataSource as DataTable;
      GridView gvv = gc.MainView as GridView; 
      if (dtColumns != null && dtColumns.Rows.Count > 0)
      {
          DataTable dtSetting = new DataTable("GridSetting");
          dtSetting.Columns.Add("ColumnsName", typeof(String));
          dtSetting.Columns.Add("isDisplay", typeof(Boolean));
          dtSetting.Columns.Add("Freeze", typeof(String));
          dtSetting.Columns.Add("ColumnsWidth", typeof(Int32));
          dtSetting.Columns.Add("Order1", typeof(String));
          dtSetting.Columns.Add("Order2", typeof(String));
          dtSetting.Columns.Add("Top", typeof(String));
          dtSetting.Columns.Add("Button", typeof(String));
          dtSetting.Columns.Add("iOrder", typeof(Int32));
  
          if (!File.Exists(sPath))
          { 
              for (int i = 0; i < gvv.VisibleColumns.Count; i++)
              {
                  string colName = gvv.VisibleColumns[i].Name.Replace("col", "");
                  dtSetting.Rows.Add(new object[] { colName, true, "無", 120, "上移", "下移", "置頂", "置底", gvv.VisibleColumns[i].VisibleIndex });
              }
          }
          else
          {
              //讀取XML 綁定數據源
              XDocument xdoc = XDocument.Load(sPath);
              var query = from a in xdoc.Descendants("Columns")
                          select new
                          {
                              ColumnsName = a.Attribute("ColumnsName").Value,
                              isDisplay = a.Element("isDisplay").Value,
                              Freeze = a.Element("Freeze").Value,
                              ColumnsWidth = a.Element("ColumnsWidth").Value,
                              iOrder = a.Element("iOrder").Value
                          };
              int index = 0;
              foreach (var item in query.ToList())
              {
                  dtSetting.Rows.Add(new object[] { item.ColumnsName, Boolean.Parse(item.isDisplay), item.Freeze, int.Parse(item.ColumnsWidth), "上移", "下移", "置頂", "置底", index });
                  index++;//排序重置
              }
          }
          gcSetting.DataSource = dtSetting;
          repositoryItemButtonEdit1.ButtonClick += RepositoryItemButtonEdit1_ButtonClick;//上移 
          repositoryItemButtonEdit2.ButtonClick += RepositoryItemButtonEdit2_ButtonClick;//下移 
          repositoryItemButtonEdit3.ButtonClick += RepositoryItemButtonEdit3_ButtonClick;//置頂 
          repositoryItemButtonEdit4.ButtonClick += RepositoryItemButtonEdit4_ButtonClick;//置底 
      }
  }

   網格窗體點擊確認,用來保存用戶的配置信息:

/// <summary>
/// 確定
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSure_Click(object sender, EventArgs e)
{
    try
    {
        //保存動作
        string sPath = $@"{ Application.StartupPath}\Task.xml";
    loop:
        if (!File.Exists(sPath))
        {
            File.Create(sPath).Close();
            XDocument xdoc = new XDocument();
            //創建跟節點
            XElement root = new XElement("Mes");
            //添加跟節點
            xdoc.Add(root);

            DataTable dtSetting = gcSetting.DataSource as DataTable;
            int index = 0;
            foreach (DataRow item in dtSetting.Rows)
            {
                //創建person節點 
                XElement per = new XElement("Columns");
                //添加person節點
                root.Add(per);
                //創建屬性節點
                XAttribute ColumnsName = new XAttribute("ColumnsName", item["ColumnsName"].ToString());
                //name節點
                XElement isDisplay = new XElement("isDisplay", item["isDisplay"].ToString());

                XElement Freeze = new XElement("Freeze", item["Freeze"].ToString());

                XElement ColumnsWidth = new XElement("ColumnsWidth", item["ColumnsWidth"].ToString());

                XElement iOrder = new XElement("iOrder", index);
                //對person節點添加id屬性 以及name sex age節點
                per.Add(ColumnsName, isDisplay, Freeze, ColumnsWidth, iOrder);
                index++;
            }
            //保存linq to xml 文件
            xdoc.Save(sPath);
        }
        else
        {
            File.Delete(sPath);
            goto loop;
        }

        //刷新原始界面顯示
        if (RefreshMDIFormEvent != null)
        {
            RefreshMDIFormEvent();
        }
    }
    catch (Exception ex)
    {

    }
    finally
    {

        this.Close();
    }
}

    因最近項目上線,時間緊迫(吃飯時間寫的博客)。作者就偷個懶,每次確認都會先刪除配置文件,然后重新新增。實際項目中可以通過更新來處理。而且goto語法也比較low,大家將就着看下效果,具體更好實現,伙伴們可以自行重寫。唯一值得注意的點是File文件流的問題,此處偷懶寫法

File.Create(sPath).Close();

   防止保存配置文件的時候,提示文件被其他用戶占用的問題。至於上移,下移,置頂,置底等功能網上很多示例,也可以公眾號私聊作者,所有源碼免費贈送。配置文件如圖:

  
  配置界面梳理完畢,只需要在主窗體數據加載后,讀取配置文件信息變更即可:

kzxGridControl1.DataSource = dataTable;
GridView gv = this.kzxGridControl1.MainView as GridView;
//讀取配置文件,更新網格狀態
string sPath = $@"{ Application.StartupPath}\Task.xml";
if (File.Exists(sPath))
{
    XDocument xdoc = XDocument.Load(sPath);
    for (int i = 0; i < gv.Columns.Count; i++)
    {
        string colName = gv.Columns[i].Name.Replace("col", "");
        var query = (from a in xdoc.Descendants("Columns")
                     where a.Attribute("ColumnsName").Value == colName
                     select new
                     {
                         isDisplay = a.Element("isDisplay").Value,
                         Freeze = a.Element("Freeze").Value,
                         ColumnsWidth = a.Element("ColumnsWidth").Value,
                         iOrder = a.Element("iOrder").Value
                     }).FirstOrDefault();
        if (query != null)
        {
            gv.Columns[i].Visible = Boolean.Parse(query.isDisplay);
            if (query.Freeze.ToLower().Equals("無"))
            {
                gv.Columns[i].Fixed = FixedStyle.None;
            }
            else if (query.Freeze.ToLower().Equals("左邊"))
            {
                gv.Columns[i].Fixed = FixedStyle.Left;
            }
            else if (query.Freeze.ToLower().Equals("右邊"))
            {
                gv.Columns[i].Fixed = FixedStyle.Right;
            }
            if (!Boolean.Parse(query.isDisplay))
            {
                gv.Columns[i].VisibleIndex = -1;
                gv.Columns[i].Visible = Boolean.Parse(query.isDisplay);
            }
            else
            {
                gv.Columns[i].VisibleIndex = int.Parse(query.iOrder);
            }
            gv.Columns[i].Width = int.Parse(query.ColumnsWidth);
        }
    }
}

   為了能實時更新配置效果,可在配置窗體添加個委托用於刷新主界面數據:

public delegate void RefreshMDIFormHandler();

  

public event RefreshMDIFormHandler RefreshMDIFormEvent;

  

 /// <summary>
/// 網格狀態設置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void kzxSimpleButton2_Click(object sender, EventArgs e)
{
    frm_GridSetting frm = new frm_GridSetting(kzxGridControl1);
    frm.RefreshMDIFormEvent += Frm_RefreshMDIFormEvent;
    frm.ShowDialog();
}

private void Frm_RefreshMDIFormEvent()
{
    this.frm_ShowControl_Load(null, null);
}

  

   時間緊急,處理的比較粗糙,直接調用load重新加載了。

  完成!所有實現處理完成,來一起看看效果:

 

 

(原圖效果)

(Telephone列上移下移確定后效果)

(Email列置頂效果)

(隱藏列效果)

(列寬設置效果)

(motto左凍結效果)

(右凍結效果)

    為了后續其他控件加載問題,本篇用按鈕方式實現的彈窗,有需求的伙伴們可以把相關代碼移動到GridContrl用戶控件的右鍵菜單中實現。此處不在過多闡述。謝謝屏幕前您的耐心陪伴!

結束語

    由於后續所有重寫/重繪控件都在同一個項目使用,而且Dev系統引用文件較多,壓縮后源碼文件仍然很大,如果有需要源碼的朋友,可以微信公眾號聯系博主,源碼可以免費贈予~!有疑問的也可以CALL我一起探討。

    最后,感謝您的耐心陪伴!如果覺得本篇博文對您或者身邊朋友有幫助的,麻煩點個關注!贈人玫瑰,手留余香,您的支持就是我寫作最大的動力,感謝您的關注,期待和您一起探討!再會!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM