C# 拓展ComboBox设置线条属性
目前由于项目需要,要实现线条属性设置的功能,就如Visio中点击线端时,可以弹出一个窗口设置线条的各种属性。
其中线条属性选择时,是在ComboBox控件中,显示各种箭头或者颜色等,此时就需要拓展ComboBox组件了。
开始做这个程序时,我没有思路,在csdn上参考一位伙伴的程序,他主要是实现了颜色的设置。
废话不多说了,上图看看:
步骤一:新建Winform工程
先添加用户组件继承自ComboBox。
系统自动生成的代码:
<span style="font-family:Arial;"><span style="font-size:24px;"> </span><span style="font-size:14px;"> public partial class MyColorComboBox : ComboBox
{
public MyColorComboBox()
{
InitializeComponent();
InitItems();
}
public MyColorComboBox(IContainer container)
{
container.Add(this);
InitializeComponent();
InitItems();
}
}</span></span>
因为我们要显示箭头或者颜色,都是需要自己绘制图形的。
步骤二:设置自定义组件的一些属性
<span style="font-family:Arial;font-size:14px;"> private void InitItems()
{
this.DrawMode = DrawMode.OwnerDrawFixed;//手动绘制所有元素
this.DropDownStyle = ComboBoxStyle.DropDownList;//下拉框样式设置为不能编辑
this.Items.Clear();//清空原有项
}</span>
<span style="font-family:Arial;font-size:14px;"> public enum LineType
{
TheStartOfLineWithArrow=0,//起始点有箭头
TheEndOfLineWithArrow,//终止点有箭头
LineWithArrows,//线的两端带箭头
TheStartOfBoldLineWithArrow,//粗线起始点带箭头
TheEndOfBoldLineWithArrow,//粗线终止点带箭头
BoldLineWithArrows,//粗线两端带箭头
TheStartOfLineWithPoint,//起始点带圆点
TheEndOfLineWithPoint,//终止点带圆点
LineWithPoints,//线两端带圆点
MoreLineType//更多线型选项
}</span>
步骤三:重写OnDrawItem方法
然后在OnDrawItem中写绘制线条的方法
这里主要是使用e.Graphics绘制图形了。
<span style="font-family:Arial;font-size:14px;"> protected override void OnDrawItem(DrawItemEventArgs e)
{
if (e.Index >= 0)//判断是否需要重绘
{
int typeId = int.Parse(this.Items[e.Index].ToString());//获取选项id
Font font = new Font("宋体", 9);//定义字体
Rectangle rect = e.Bounds;
rect.Inflate(-2, -2);//缩放一定大小
Pen pen = null;
SolidBrush solidBrush = new SolidBrush(Color.Black);
float offSet = rect.Height / 2;
float x = rect.Width / 10;
float y = rect.Top + offSet;//如果设置成e.ItemHeigh*e.Index +offSet,则在选中节点后,由于Item位置固定,因此Item不能显示出来。
switch (typeId)
{
case (int)LineType.TheStartOfLineWithArrow:
pen = new Pen(Color.Black, 1);
e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(x + offSet, y - offSet));//绘制起始点带箭头的线
e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(x + offSet, y + offSet));
break;
case (int)LineType.TheEndOfLineWithArrow:
pen = new Pen(Color.Black, 1);
e.Graphics.DrawLine(pen, new PointF(8 * x, y), new PointF(8 * x - offSet, y - offSet));//绘制终端带箭头的线
e.Graphics.DrawLine(pen, new PointF(8 * x, y), new PointF(8 * x - offSet, y + offSet));
break;
case (int)LineType.LineWithArrows:
pen = new Pen(Color.Black, 1);
e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(x + offSet, y - offSet));//绘制两端带箭头的线
e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(x + offSet, y + offSet));
e.Graphics.DrawLine(pen, new PointF(8 * x, y), new PointF(8 * x - offSet, y - offSet));
e.Graphics.DrawLine(pen, new PointF(8 * x, y), new PointF(8 * x - offSet, y + offSet));
break;
case (int)LineType.TheStartOfBoldLineWithArrow:
pen = new Pen(Color.Black, 2);
e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(x + offSet, y - offSet));//绘制起始端带箭头的粗线
e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(x + offSet, y + offSet));
break;
case (int)LineType.TheEndOfBoldLineWithArrow:
pen = new Pen(Color.Black, 2);
e.Graphics.DrawLine(pen, new PointF(8 * x, y), new PointF(8 * x - offSet, y - offSet));//绘制终端带箭头的粗线
e.Graphics.DrawLine(pen, new PointF(8 * x, y), new PointF(8 * x - offSet, y + offSet));
break;
case (int)LineType.BoldLineWithArrows:
pen = new Pen(Color.Black, 2);
e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(x + offSet, y - offSet));
e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(x + offSet, y + offSet));
e.Graphics.DrawLine(pen, new PointF(8 * x, y), new PointF(8 * x - offSet, y - offSet));
e.Graphics.DrawLine(pen, new PointF(8 * x, y), new PointF(8 * x - offSet, y + offSet));
break;
case (int)LineType.TheStartOfLineWithPoint:
pen = new Pen(Color.Black, 1);
e.Graphics.FillEllipse(solidBrush, new Rectangle(new Point((int)x - 3, (int)y - 3), new Size(8, 8)));//绘制起始端带圆的线
break;
case (int)LineType.TheEndOfLineWithPoint:
pen = new Pen(Color.Black, 1);
e.Graphics.FillEllipse(solidBrush, new Rectangle(new Point((int)(8 * x) - 3, (int)y - 3), new Size(8, 8)));//绘制终端带圆的线
break;
case (int)LineType.LineWithPoints:
pen = new Pen(Color.Black, 1);
e.Graphics.FillEllipse(solidBrush, new Rectangle(new Point((int)x - 3, (int)y - 3), new Size(8, 8)));//绘制两端都带圆的线
e.Graphics.FillEllipse(solidBrush, new Rectangle(new Point((int)(8 * x) - 3, (int)y - 3), new Size(8, 8)));
break;
case (int)LineType.MoreLineType:
e.Graphics.DrawString("更多线型选项...", font, solidBrush, new PointF(x - 3, y - offSet));
break;
default:
pen = new Pen(Color.Black, 1);
break;
}
if (e.Index < 9)
{
e.Graphics.DrawLine(pen, new PointF(x, y), new PointF(8 * x, y));//绘制线
Rectangle rectColor = new Rectangle(rect.Location, new Size(9 * (int)x, rect.Height));
e.Graphics.DrawRectangle(Pens.Black, rectColor);//绘制边框
}
}
}</span>
这个坐标的设置可能麻烦了些,不过具体实现就是这样了。
步骤四:保存程序后,编译程序,可以在工具箱--指针栏看到MyLineComboBox这个自定义组件了。
然后在Form中添加它,再添加MyLineComboBox的Items(0,1,2,3,4,5,6,7,8,9)。
运行程序,可以效果了,当然这里还需要自己再拓展。