利用CustomDrawNodeCell 的DrawImage重繪小圖示

CassiezzZ發表於2020-11-17

要求:基於在treeList控制元件實現如下要求:

1.TreeListNode的Cell加小圖示

這樣的需求應該很多,個人覺得是比較簡單的,不多說直接上程式碼:

private TreeListColumn statusClumn;
private System.Windows.Forms.ImageList imageList;
void treeList1_CustomDrawNodeCell(object sender, CustomDrawNodeCellEventArgs e)
        {
            if(e.Column.FieldName != statusClumn.FieldName )
             {
               return;
            }
             //從imageList拿到下標為的圖片物件
             Image image = imageList.Images[0];
             //繪製座標設定XY和高寬
             Rectangle rectangle = new Rectangle(e.Bounds.X + 5, e.Bounds.Y + (e.Bounds.Height - image.Height) / 2, image.Width, image.Height)
             //執行繪製方法
             e.Cache.Graphics.DrawImage(image, rectangle );
             //將重繪前的背景色再次繪製上去
             e.Cache.FillRectangle(e.Appearance.GetBackBrush(e.Cache), e.Bounds);
             //將重繪前的文字樣式再次繪製上去
             e.Cache.DrawString(e.CellText, e.Appearance.Font, e.Appearance.GetForeBrush(e.Cache), e.Bounds, e.Appearance.GetStringFormat());
             //標記執行處理,一旦為true,底層會抹除statusClumn的樣式效果,因此需重新設定FillRectangle和DrawString資訊
             e.Handled = true;
        }

2.滑鼠懸停時改變小圖示

在CustomDrawNodeCell事件中無法獲取到滑鼠是否懸停,那麼我們可以通過獲取懸停背景色確定是否懸停,如程式碼所示:

private TreeListColumn statusClumn;
private System.Windows.Forms.ImageList imageList;
void treeList1_CustomDrawNodeCell(object sender, CustomDrawNodeCellEventArgs e)
        {
            if(e.Column.FieldName != statusClumn.FieldName )
             {
               return;
            }
            //假設懸停背景色
            Color hoverColor = Color.Red;
            //從ImageList元件拿到下指定標為的圖片物件,預設顯示下標0的圖示
            Image image = imageList.Images[0];
            if(e.Appearance.BackColor == hoverColor) {
                //懸停 顯示 圖片
                image = imageList.Images[1];
            }
             //繪製座標設定XY和高寬
             Rectangle rectangle = new Rectangle(e.Bounds.X + 5, e.Bounds.Y + (e.Bounds.Height - image.Height) / 2, image.Width, image.Height)
             //執行繪製方法
             e.Cache.Graphics.DrawImage(image, rectangle );
             //將重繪前的背景色再次繪製上去
             e.Cache.FillRectangle(e.Appearance.GetBackBrush(e.Cache), e.Bounds);
             //將重繪前的文字樣式再次繪製上去
             e.Cache.DrawString(e.CellText, e.Appearance.Font, e.Appearance.GetForeBrush(e.Cache), e.Bounds, e.Appearance.GetStringFormat());
             //標記執行處理,一旦為true,底層會抹除statusClumn的樣式效果,因此需重新設定FillRectangle和DrawString資訊
             e.Handled = true;
        }

3.展示資料關係小圖示

UID名稱描述關係
A☺序列A主序列A
A1☺序列A1從序列A
A2序列A2新從序列AA,A1,A2
B序列B主序列B
B1序列B從序列B
B2序列B新從序列BB,B1,B2

結合上表格內容,我們需要做到這樣的效果:
關係:主序列+從序列=新從序列
滑鼠選中新從序列時,需要將主從新序列的關係用☺圖片標記(因不知道怎麼表格插入圖片,暫時用符號代替)

由於非新從序列是沒有關係這欄資訊,因此我們需要先將需要標記的資料做個標記,在使用CustomDrawNodeCell事件處理
在AfterFocusNode事件標記好關係:

         /// <summary>
        /// 設定新序列與原序列關係
        /// <param name="enode">當前選中資料行的節點物件</param>
        /// </summary>
        public void SetRelated(TreeListNode enode)
        {
            //清除標記的關係
            foreach (TreeListNode node in this.treeList.Nodes)
            {
                node.SetValue("MarkRelated", "");
            }

            //取出關係欄位
            string related = enode.GetValue("關係").ToString();

            //不存在關係,直接返回
            if (related == null)
            {
                return;
            }
            //迴圈將序列的關係設定到MarkRelated屬性中
            foreach (TreeListNode node in this.treeList.Nodes)
            {
                if (related .IndexOf(node.GetValue("UID").ToString()) == -1)
                {
                    continue;
                }
                node.SetValue("MarkRelated", "Mark");
            }
        }

設定關係後的表格如下:

UID名稱描述關係MarkRelated
A☺序列A主序列AMark
A1☺序列A1從序列AMark
A2序列A2新從序列AA,A1,A2Mark
B序列B主序列B
B1序列B從序列B
B2序列B新從序列BB,B1,B2

在CustomDrawNodeCell事件繪製關係:

private TreeListColumn nameClumn;
void treeList1_CustomDrawNodeCell(object sender, CustomDrawNodeCellEventArgs e)
{
      if(e.Column.FieldName != nameClumn.FieldName )
      {
         return;
      }
      //假設懸停背景色
      Color hoverColor = Color.Red;
      if (!StringUtils.IsEmpty(e.Node.GetValue("MarkRelated")) && e.Node.GetValue("MarkRelated") .toString()=="Mark")
      {
            //預設關係圖示
            Image image = imageList3.Images[0];
            //選中狀態 或 背景是懸停顏色時 關係圖示
            if (e.Node.Selected || e.Appearance.BackColor == hoverColor )
            {
                     image = imageList3.Images[1];
            }
            //繪製“關係”圖示
            Rectangle rect = new Rectangle(e.Bounds.X + 5, e.Bounds.Y + (e.Bounds.Height - image.Height) / 2, image.Width, image.Height);
            e.Cache.Graphics.DrawImage(image, rect );
      }
      //將重繪前的背景色再次繪製上去
      e.Cache.FillRectangle(e.Appearance.GetBackBrush(e.Cache), e.Bounds);
      //將重繪前的文字樣式再次繪製上去
      e.Cache.DrawString(e.CellText, e.Appearance.Font, e.Appearance.GetForeBrush(e.Cache), e.Bounds, e.Appearance.GetStringFormat());
      //標記執行處理,一旦為true,底層會抹除statusClumn的樣式效果,因此需重新設定FillRectangle和DrawString資訊
      e.Handled = true;
}

相關文章