C# 拓展ComboBox設置線條屬性
目前由於項目需要,要實現線條屬性設置的功能,就如Visio中點擊線端時,可以彈出一個窗口設置線條的各種屬性。
其中線條屬性選擇時,是在ComboBox控件中,顯示各種箭頭或者顏色等,此時就需要拓展ComboBox組件了。
開始做這個程序時,我沒有思路,在csdn上參考一位伙伴的程序,他主要是實現了顏色的設置。
廢話不多說了,上圖看看:
步驟一:新建Winform工程
先添加用戶組件繼承自ComboBox。
系統自動生成的代碼:
1 public partial class MyColorComboBox : ComboBox 2 { 3 public MyColorComboBox() 4 { 5 InitializeComponent(); 6 InitItems(); 7 } 8 9 public MyColorComboBox(IContainer container) 10 { 11 container.Add(this); 12 InitializeComponent(); 13 InitItems(); 14 } 15 }
因為我們要顯示箭頭或者顏色,都是需要自己繪制圖形的。
步驟二:設置自定義組件的一些屬性
1 private void InitItems() 2 { 3 this.DrawMode = DrawMode.OwnerDrawFixed;//手動繪制所有元素 4 this.DropDownStyle = ComboBoxStyle.DropDownList;//下拉框樣式設置為不能編輯 5 this.Items.Clear();//清空原有項 6 }
1 public enum LineType 2 { 3 TheStartOfLineWithArrow=0,//起始點有箭頭 4 TheEndOfLineWithArrow,//終止點有箭頭 5 LineWithArrows,//線的兩端帶箭頭 6 TheStartOfBoldLineWithArrow,//粗線起始點帶箭頭 7 TheEndOfBoldLineWithArrow,//粗線終止點帶箭頭 8 BoldLineWithArrows,//粗線兩端帶箭頭 9 TheStartOfLineWithPoint,//起始點帶圓點 10 TheEndOfLineWithPoint,//終止點帶圓點 11 LineWithPoints,//線兩端帶圓點 12 MoreLineType//更多線型選項 13 }
步驟三:重寫OnDrawItem方法
然后在OnDrawItem中寫繪制線條的方法
這里主要是使用e.Graphics繪制圖形了。
1 protected override void OnDrawItem(DrawItemEventArgs e) 2 { 3 if (e.Index >= 0)//判斷是否需要重繪 4 { 5 int typeId = int.Parse(this.Items[e.Index].ToString());//獲取選項id 6 7 Font font = new Font("宋體", 9);//定義字體 8 Rectangle rect = e.Bounds; 9 rect.Inflate(-2, -2);//縮放一定大小 10 Pen pen = null; 11 SolidBrush solidBrush = new SolidBrush(Color.Black); 12 13 float offSet = rect.Height / 2; 14 float x = rect.Width / 10; 15 float y = rect.Top + offSet;//如果設置成e.ItemHeigh*e.Index +offSet,則在選中節點后,由於Item位置固定,因此Item不能顯示出來。 16 17 switch (typeId) 18 { 19 case (int)LineType.TheStartOfLineWithArrow: 20 pen = new Pen(Color.Black, 1); 21 e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(x + offSet, y - offSet));//繪制起始點帶箭頭的線 22 e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(x + offSet, y + offSet)); 23 break; 24 case (int)LineType.TheEndOfLineWithArrow: 25 pen = new Pen(Color.Black, 1); 26 e.Graphics.DrawLine(pen, new PointF(8 * x, y), new PointF(8 * x - offSet, y - offSet));//繪制終端帶箭頭的線 27 e.Graphics.DrawLine(pen, new PointF(8 * x, y), new PointF(8 * x - offSet, y + offSet)); 28 break; 29 case (int)LineType.LineWithArrows: 30 pen = new Pen(Color.Black, 1); 31 e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(x + offSet, y - offSet));//繪制兩端帶箭頭的線 32 e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(x + offSet, y + offSet)); 33 e.Graphics.DrawLine(pen, new PointF(8 * x, y), new PointF(8 * x - offSet, y - offSet)); 34 e.Graphics.DrawLine(pen, new PointF(8 * x, y), new PointF(8 * x - offSet, y + offSet)); 35 break; 36 case (int)LineType.TheStartOfBoldLineWithArrow: 37 pen = new Pen(Color.Black, 2); 38 e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(x + offSet, y - offSet));//繪制起始端帶箭頭的粗線 39 e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(x + offSet, y + offSet)); 40 break; 41 case (int)LineType.TheEndOfBoldLineWithArrow: 42 pen = new Pen(Color.Black, 2); 43 e.Graphics.DrawLine(pen, new PointF(8 * x, y), new PointF(8 * x - offSet, y - offSet));//繪制終端帶箭頭的粗線 44 e.Graphics.DrawLine(pen, new PointF(8 * x, y), new PointF(8 * x - offSet, y + offSet)); 45 break; 46 case (int)LineType.BoldLineWithArrows: 47 pen = new Pen(Color.Black, 2); 48 e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(x + offSet, y - offSet)); 49 e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(x + offSet, y + offSet)); 50 e.Graphics.DrawLine(pen, new PointF(8 * x, y), new PointF(8 * x - offSet, y - offSet)); 51 e.Graphics.DrawLine(pen, new PointF(8 * x, y), new PointF(8 * x - offSet, y + offSet)); 52 break; 53 case (int)LineType.TheStartOfLineWithPoint: 54 pen = new Pen(Color.Black, 1); 55 e.Graphics.FillEllipse(solidBrush, new Rectangle(new Point((int)x - 3, (int)y - 3), new Size(8, 8)));//繪制起始端帶圓的線 56 break; 57 case (int)LineType.TheEndOfLineWithPoint: 58 pen = new Pen(Color.Black, 1); 59 e.Graphics.FillEllipse(solidBrush, new Rectangle(new Point((int)(8 * x) - 3, (int)y - 3), new Size(8, 8)));//繪制終端帶圓的線 60 break; 61 case (int)LineType.LineWithPoints: 62 pen = new Pen(Color.Black, 1); 63 e.Graphics.FillEllipse(solidBrush, new Rectangle(new Point((int)x - 3, (int)y - 3), new Size(8, 8)));//繪制兩端都帶圓的線 64 e.Graphics.FillEllipse(solidBrush, new Rectangle(new Point((int)(8 * x) - 3, (int)y - 3), new Size(8, 8))); 65 break; 66 case (int)LineType.MoreLineType: 67 e.Graphics.DrawString("更多線型選項...", font, solidBrush, new PointF(x - 3, y - offSet)); 68 break; 69 default: 70 pen = new Pen(Color.Black, 1); 71 break; 72 } 73 if (e.Index < 9) 74 { 75 e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(8 * x, y));//繪制線 76 Rectangle rectColor = new Rectangle(rect.Location, new Size(9 * (int)x, rect.Height)); 77 e.Graphics.DrawRectangle(Pens.Black, rectColor);//繪制邊框 78 79 } 80 } 81 }
這個坐標的設置可能麻煩了些,不過具體實現就是這樣了。
步驟四:保存程序后,編譯程序,可以在工具箱--指針欄看到MyLineComboBox這個自定義組件了。
然后在Form中添加它,再添加MyLineComboBox的Items(0,1,2,3,4,5,6,7,8,9)。
運行程序,可以效果了,當然這里還需要自己再拓展。