PropertyGrid 下拉式和弹出编辑框的实现:
首先copy以下三个类
namespace WindowsFormsApp3
{
public class hhh
{
private double _angle;
[BrowsableAttribute(true)]
[EditorAttribute(typeof(AngleEditor), typeof(System.Drawing.Design.UITypeEditor))]
public double Angle
{
get
{ return _angle; }
set
{ _angle = value; }
}
}
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class AngleEditor : System.Drawing.Design.UITypeEditor
{
public AngleEditor()
{
}
//下拉式还是弹出式
public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
// 为属性显示UI编辑框
public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)
{
//值类型不为double,直接返回value
if (value.GetType() != typeof(double))
return value;
//值为double,显示下拉式或弹出编辑框
IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (edSvc != null)
{
// 显示编辑框并初始化编辑框的值
AngleControl angleControl = new AngleControl((double)value);
edSvc.ShowDialog(angleControl);
// 返回编辑框中编辑的值.
if (value.GetType() == typeof(double))
return angleControl.angle;
}
return value;
}
//下面两个函数是为了在PropertyGrid中显示一个辅助的效果
//可以不用重写
public override void PaintValue(System.Drawing.Design.PaintValueEventArgs e)
{
int normalX = (e.Bounds.Width / 2);
int normalY = (e.Bounds.Height / 2);
e.Graphics.FillRectangle(new SolidBrush(Color.DarkBlue), e.Bounds.X, e.Bounds.Y, e.Bounds.Width, e.Bounds.Height);
e.Graphics.FillEllipse(new SolidBrush(Color.White), e.Bounds.X + 1, e.Bounds.Y + 1, e.Bounds.Width - 3, e.Bounds.Height - 3);
e.Graphics.FillEllipse(new SolidBrush(Color.SlateGray), normalX + e.Bounds.X - 1, normalY + e.Bounds.Y - 1, 3, 3);
double radians = ((double)e.Value * Math.PI) / (double)180;
e.Graphics.DrawLine(new Pen(new SolidBrush(Color.Red), 1), normalX + e.Bounds.X, normalY + e.Bounds.Y,
e.Bounds.X + (normalX + (int)((double)normalX * Math.Cos(radians))),
e.Bounds.Y + (normalY + (int)((double)normalY * Math.Sin(radians))));
}
public override bool GetPaintValueSupported(System.ComponentModel.ITypeDescriptorContext context)
{
return true;
}
}
// 这里是我们要显示出来的编辑器,把它作为一个内置类
//从UserControl继承,要在上面EditValue函数中使用的
internal class AngleControl : System.Windows.Forms.Form
{
public double angle; //编辑的角度
private float x; //鼠标位置
private float y;
public AngleControl(double initial_angle)
{
this.angle = initial_angle;
}
//显现时,显示属性的当前值
protected override void OnLoad(EventArgs e)
{
int originX = (this.Width / 2);
int originY = (this.Height / 2);
this.x = (float)(50 * Math.Cos(this.angle * Math.PI / 180) + originX);
this.y = (float)(50 * Math.Sin(this.angle * Math.PI / 180) + originY);
base.OnLoad(e);
}
//绘制控件,用来显示编辑角度
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
int originX = (this.Width / 2);
int originY = (this.Height / 2);
e.Graphics.DrawEllipse(Pens.Black, originX - 50, originY - 50, 100, 100);
e.Graphics.DrawLine(Pens.Black, originX, originY, x, y);
e.Graphics.DrawString("Angle:" + this.angle, this.Font, Brushes.Red, 0, 0);
}
//鼠标移动时设置角度
protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
int originX = (this.Width / 2);
int originY = (this.Height / 2);
double len = Math.Sqrt(Math.Pow(e.X - originX, 2) + Math.Pow(e.Y - originY, 2));
double h = e.Y - originY;
this.angle = Math.Asin(h / len);
if ((e.X >= originX && e.Y >= originY))
{
this.x = (float)(50 * Math.Cos(this.angle) + originX);
this.y = (float)(50 * Math.Sin(this.angle) + originY);
this.angle = this.angle * 180 / Math.PI;
}
else if (e.X < originX && e.Y > originY)
{
this.x = (float)(originX - 50 * Math.Cos(this.angle));
this.y = (float)(50 * Math.Sin(this.angle) + originY);
this.angle = 180 - this.angle * 180 / Math.PI;
}
else if (e.X < originX && e.Y < originY)
{
this.x = (float)(originX - 50 * Math.Cos(this.angle));
this.y = (float)(originY + 50 * Math.Sin(this.angle));
this.angle = 180 - this.angle * 180 / Math.PI;
}
else if (e.X >= originX && e.Y <= originY)
{
this.x = (float)(originX + 50 * Math.Cos(this.angle));
this.y = (float)(originY + 50 * Math.Sin(this.angle));
this.angle = 360 + this.angle * 180 / Math.PI;
}
this.Invalidate();
}
}
}
}
2.新建一个form,界面上添加一个propertygrid控件。然后添加以下代码
namespace WindowsFormsApp3
{
public partial class Form1 : Form
{
OptionsInfo m_optInfo = new OptionsInfo();
public Form1()
{
InitializeComponent();
string extraParam = "Extra param from main form";
TypeDescriptor.AddProvider(new BarTypeDescriptionProvider(typeof(Bar), extraParam), typeof(Bar));
this.propertyGrid1.SelectedObject = new hhh();
}
private void button_cancel_Click(object sender, EventArgs e)
{
}
}
}
弹出式效果如下:
3.下拉式只需要修改三个地方代码即可实现
修改地方如下:
(1)
(2)
(3)
效果如下