UITypeEditor 类
提供可用于设计值编辑器的基类,这些编辑器可提供用户界面 (UI),用来表示和编辑所支持的数据类型的对象值。
**命名空间:**System.Drawing.Design
**程序集:**System.Drawing(在 system.drawing.dll 中)
语法
声明
Public Class UITypeEditor
用法
Dim instance As UITypeEditor
public class UITypeEditor
public ref class UITypeEditor
public class UITypeEditor
public class UITypeEditor
备注
UITypeEditor 类提供一种基类,可以从该基类派生和进行扩展,以便为设计时环境实现自定义类型编辑器。在文本框值编辑器不足以有效地选择某些类型的值的情况下,自定义类型编辑器非常有用。
若要实现自定义设计时 UI 类型编辑器,必须执行下列步骤:
定义一个从 UITypeEditor 派生的类。
重写 EditValue 方法以处理用户界面、用户输入操作以及值的分配。
重写 GetEditStyle 方法,以便将编辑器将使用的编辑器样式的类型通知给“属性”窗口。
通过执行下列步骤,可以为在“属性”窗口中绘制值的表示形式添加附加支持:
重写 GetPaintValueSupported 方法以指示编辑器支持显示值的表示形式。
重写 PaintValue 方法以实现该值的表示形式的显示。
如果编辑器应具有初始化行为,则重写 UITypeEditor 构造函数方法。
提示
UITypeEditor 类不支持从右向左 (RTL) 的布局。
有关增强设计时支持的更多信息,请参见 扩展设计时支持。有关实现 UITypeEditor 的更多信息,请参见 用户界面类型编辑器概述。
示例
下面的代码示例演示如何使用 EditorAttribute 将 UITypeEditor 与 integer、double 或 float 属性相关联,以便在设计模式的“属性”窗口提供角度选择界面。此示例使用 IWindowsFormsEditorService 界面在设计模式的“属性”窗口中显示下拉控件。编译此代码并使用 Visual Studio 的“工具”菜单上的“自定义工具箱”命令将程序集添加到“工具箱”。创建 AngleTestControl
的实例,并在“属性”窗口中的 Angle 属性旁单击下拉按钮以便使用编辑器配置属性。
Option Strict Off
Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Design
Imports System.Reflection
Imports System.Windows.Forms
Imports System.Windows.Forms.Design
' This UITypeEditor can be associated with Int32, Double and Single
' properties to provide a design-mode angle selection interface.
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
Public Class AngleEditor
Inherits System.Drawing.Design.UITypeEditor
Public Sub New()
End Sub
' Indicates whether the UITypeEditor provides a form-based (modal) dialog,
' drop down dialog, or no UI outside of the properties window.
Public Overloads Overrides Function GetEditStyle(ByVal context As System.ComponentModel.ITypeDescriptorContext) As System.Drawing.Design.UITypeEditorEditStyle
Return UITypeEditorEditStyle.DropDown
End Function
' Displays the UI for value selection.
Public Overloads Overrides Function EditValue(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal provider As System.IServiceProvider, ByVal value As Object) As Object
' Return the value if the value is not of type Int32, Double and Single.
If Not value.GetType() Is GetType(Double) Or value.GetType() Is GetType(Single) Or value.GetType() Is GetType(Integer) Then
Return value
End If
' Uses the IWindowsFormsEditorService to display a
' drop-down UI in the Properties window.
Dim edSvc As IWindowsFormsEditorService = CType(provider.GetService(GetType(IWindowsFormsEditorService)), IWindowsFormsEditorService)
If Not (edSvc Is Nothing) Then
' Display an angle selection control and retrieve the value.
Dim angleControl As New AngleControl(System.Convert.ToDouble(value))
edSvc.DropDownControl(angleControl)
' Return the value in the appropraite data format.
If value Is GetType(Double) Then
Return angleControl.angle
ElseIf value Is GetType(Single) Then
Return System.Convert.ToSingle(angleControl.angle)
ElseIf value Is GetType(Integer) Then
Return System.Convert.ToInt32(angleControl.angle)
End If
End If
Return value
End Function
' Draws a representation of the property's value.
Public Overloads Overrides Sub PaintValue(ByVal e As System.Drawing.Design.PaintValueEventArgs)
Dim normalX As Integer = e.Bounds.Width / 2
Dim normalY As Integer = e.Bounds.Height / 2
' Fill background and ellipse and center point.
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)
' Draw line along the current angle.
Dim radians As Double = System.Convert.ToDouble(e.Value) * Math.PI / System.Convert.ToDouble(180)
e.Graphics.DrawLine(New Pen(New SolidBrush(Color.Red), 1), normalX + e.Bounds.X, normalY + e.Bounds.Y, e.Bounds.X + (normalX + System.Convert.ToInt32(System.Convert.ToDouble(normalX) * Math.Cos(radians))), e.Bounds.Y + (normalY + System.Convert.ToInt32(System.Convert.ToDouble(normalY) * Math.Sin(radians))))
End Sub
' Indicates whether the UITypeEditor supports painting a
' representation of a property's value.
Public Overloads Overrides Function GetPaintValueSupported(ByVal context As System.ComponentModel.ITypeDescriptorContext) As Boolean
Return True
End Function
End Class
' Provides a user interface for adjusting an angle value.
Friend Class AngleControl
Inherits System.Windows.Forms.UserControl
' Stores the angle.
Public angle As Double
' Stores the rotation offset.
Private rotation As Integer = 0
' Control state tracking variables.
Private dbx As Integer = -10
Private dby As Integer = -10
Private overButton As Integer = -1
Public Sub New(ByVal initial_angle As Double)
Me.angle = initial_angle
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
' Set angle origin point at center of control.
Dim originX As Integer = Me.Width / 2
Dim originY As Integer = Me.Height / 2
' Fill background and ellipse and center point.
e.Graphics.FillRectangle(New SolidBrush(Color.DarkBlue), 0, 0, Me.Width, Me.Height)
e.Graphics.FillEllipse(New SolidBrush(Color.White), 1, 1, Me.Width - 3, Me.Height - 3)
e.Graphics.FillEllipse(New SolidBrush(Color.SlateGray), originX - 1, originY - 1, 3, 3)
' Draw angle markers.
Dim startangle As Integer = (270 - rotation) Mod 360
e.Graphics.DrawString(startangle.ToString(), New Font("Arial", 8), New SolidBrush(Color.DarkGray), Me.Width / 2 - 10, 10)
startangle = (startangle + 90) Mod 360
e.Graphics.DrawString(startangle.ToString(), New Font("Arial", 8), New SolidBrush(Color.DarkGray), Me.Width - 18, Me.Height / 2 - 6)
startangle = (startangle + 90) Mod 360
e.Graphics.DrawString(startangle.ToString(), New Font("Arial", 8), New SolidBrush(Color.DarkGray), Me.Width / 2 - 6, Me.Height - 18)
startangle = (startangle + 90) Mod 360
e.Graphics.DrawString(startangle.ToString(), New Font("Arial", 8), New SolidBrush(Color.DarkGray), 10, Me.Height / 2 - 6)
' Draw line along the current angle.
Dim radians As Double = ((angle + rotation + 360) Mod 360) * Math.PI / System.Convert.ToDouble(180)
e.Graphics.DrawLine(New Pen(New SolidBrush(Color.Red), 1), originX, originY, originX + System.Convert.ToInt32(System.Convert.ToDouble(originX) * Math.Cos(radians)), originY + System.Convert.ToInt32(System.Convert.ToDouble(originY) * Math.Sin(radians)))
' Output angle information.
e.Graphics.FillRectangle(New SolidBrush(Color.Gray), Me.Width - 84, 3, 82, 13)
e.Graphics.DrawString("Angle: " + angle.ToString("F4"), New Font("Arial", 8), New SolidBrush(Color.Yellow), Me.Width - 84, 2)
' Draw square at mouse position of last angle adjustment.
e.Graphics.DrawRectangle(New Pen(New SolidBrush(Color.Black), 1), dbx - 2, dby - 2, 4, 4)
' Draw rotation adjustment buttons.
If overButton = 1 Then
e.Graphics.FillRectangle(New SolidBrush(Color.Green), Me.Width - 28, Me.Height - 14, 12, 12)
e.Graphics.FillRectangle(New SolidBrush(Color.Gray), 2, Me.Height - 13, 110, 12)
e.Graphics.DrawString("Rotate 90 degrees left", New Font("Arial", 8), New SolidBrush(Color.White), 2, Me.Height - 14)
Else
e.Graphics.FillRectangle(New SolidBrush(Color.DarkGreen), Me.Width - 28, Me.Height - 14, 12, 12)
End If
If overButton = 2 Then
e.Graphics.FillRectangle(New SolidBrush(Color.Green), Me.Width - 14, Me.Height - 14, 12, 12)
e.Graphics.FillRectangle(New SolidBrush(Color.Gray), 2, Me.Height - 13, 116, 12)
e.Graphics.DrawString("Rotate 90 degrees right", New Font("Arial", 8), New SolidBrush(Color.White), 2, Me.Height - 14)
Else
e.Graphics.FillRectangle(New SolidBrush(Color.DarkGreen), Me.Width - 14, Me.Height - 14, 12, 12)
End If
e.Graphics.DrawEllipse(New Pen(New SolidBrush(Color.White), 1), Me.Width - 11, Me.Height - 11, 6, 6)
e.Graphics.DrawEllipse(New Pen(New SolidBrush(Color.White), 1), Me.Width - 25, Me.Height - 11, 6, 6)
If overButton = 1 Then
e.Graphics.FillRectangle(New SolidBrush(Color.Green), Me.Width - 25, Me.Height - 6, 4, 4)
Else
e.Graphics.FillRectangle(New SolidBrush(Color.DarkGreen), Me.Width - 25, Me.Height - 6, 4, 4)
End If
If overButton = 2 Then
e.Graphics.FillRectangle(New SolidBrush(Color.Green), Me.Width - 8, Me.Height - 6, 4, 4)
Else
e.Graphics.FillRectangle(New SolidBrush(Color.DarkGreen), Me.Width - 8, Me.Height - 6, 4, 4)
End If
e.Graphics.FillPolygon(New SolidBrush(Color.White), New Point() {New Point(Me.Width - 7, Me.Height - 8), New Point(Me.Width - 3, Me.Height - 8), New Point(Me.Width - 5, Me.Height - 4)})
e.Graphics.FillPolygon(New SolidBrush(Color.White), New Point() {New Point(Me.Width - 26, Me.Height - 8), New Point(Me.Width - 21, Me.Height - 8), New Point(Me.Width - 25, Me.Height - 4)})
End Sub
Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
' Handle rotation adjustment button clicks.
If e.X >= Me.Width - 28 AndAlso e.X <= Me.Width - 2 AndAlso e.Y >= Me.Height - 14 AndAlso e.Y <= Me.Height - 2 Then
If e.X <= Me.Width - 16 Then
rotation -= 90
ElseIf e.X >= Me.Width - 14 Then
rotation += 90
End If
If rotation < 0 Then
rotation += 360
End If
rotation = rotation Mod 360
dbx = -10
dby = -10
Else
UpdateAngle(e.X, e.Y)
End If
Me.Refresh()
End Sub
Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
If e.Button = System.Windows.Forms.MouseButtons.Left Then
UpdateAngle(e.X, e.Y)
overButton = -1
ElseIf e.X >= Me.Width - 28 AndAlso e.X <= Me.Width - 16 AndAlso e.Y >= Me.Height - 14 AndAlso e.Y <= Me.Height - 2 Then
overButton = 1
ElseIf e.X >= Me.Width - 14 AndAlso e.X <= Me.Width - 2 AndAlso e.Y >= Me.Height - 14 AndAlso e.Y <= Me.Height - 2 Then
overButton = 2
Else
overButton = -1
End If
Me.Refresh()
End Sub
Private Sub UpdateAngle(ByVal mx As Integer, ByVal my As Integer)
' Store mouse coordinates.
dbx = mx
dby = my
' Translate y coordinate input to GetAngle function to correct for ellipsoid distortion.
Dim widthToHeightRatio As Double = System.Convert.ToDouble(Me.Width) / System.Convert.ToDouble(Me.Height)
Dim tmy As Integer
If my = 0 Then
tmy = my
ElseIf my < Me.Height / 2 Then
tmy = Me.Height / 2 - Fix((Me.Height / 2 - my) * widthToHeightRatio)
Else
tmy = Me.Height / 2 + Fix(System.Convert.ToDouble(my - Me.Height / 2) * widthToHeightRatio)
End If
' Retrieve updated angle based on rise over run.
angle = (GetAngle(Me.Width / 2, Me.Height / 2, mx, tmy) - rotation) Mod 360
End Sub
Private Function GetAngle(ByVal x1 As Integer, ByVal y1 As Integer, ByVal x2 As Integer, ByVal y2 As Integer) As Double
Dim degrees As Double
' Avoid divide by zero run values.
If x2 - x1 = 0 Then
If y2 > y1 Then
degrees = 90
Else
degrees = 270
End If
Else
' Calculate angle from offset.
Dim riseoverrun As Double = System.Convert.ToDouble(y2 - y1) / System.Convert.ToDouble(x2 - x1)
Dim radians As Double = Math.Atan(riseoverrun)
degrees = radians * (System.Convert.ToDouble(180) / Math.PI)
' Handle quadrant specific transformations.
If x2 - x1 < 0 OrElse y2 - y1 < 0 Then
degrees += 180
End If
If x2 - x1 > 0 AndAlso y2 - y1 < 0 Then
degrees -= 180
End If
If degrees < 0 Then
degrees += 360
End If
End If
Return degrees
End Function
End Class
Public Class AngleEditorTestControl
Inherits System.Windows.Forms.UserControl
Private int_angle As Double
<BrowsableAttribute(True), EditorAttribute(GetType(AngleEditor), GetType(System.Drawing.Design.UITypeEditor))> _
Public Property Angle() As Double
Get
Return int_angle
End Get
Set(ByVal Value As Double)
int_angle = Value
End Set
End Property
Public Sub New()
int_angle = 90
Me.Size = New Size(190, 42)
Me.BackColor = Color.Beige
End Sub
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
If Me.DesignMode Then
e.Graphics.DrawString("Use the Properties Window to access", New Font("Arial", 8), New SolidBrush(Color.Black), 3, 2)
e.Graphics.DrawString("the AngleEditor UITypeEditor by", New Font("Arial", 8), New SolidBrush(Color.Black), 3, 14)
e.Graphics.DrawString("configuring the ""Angle"" property.", New Font("Arial", 8), New SolidBrush(Color.Black), 3, 26)
Else
e.Graphics.DrawString("This example requires design mode.", New Font("Arial", 8), New SolidBrush(Color.Black), 3, 2)
End If
End Sub
End Class
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
namespace AngleEditor
{
// This UITypeEditor can be associated with Int32, Double and Single
// properties to provide a design-mode angle selection interface.
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class AngleEditor : System.Drawing.Design.UITypeEditor
{
public AngleEditor()
{
}
// Indicates whether the UITypeEditor provides a form-based (modal) dialog,
// drop down dialog, or no UI outside of the properties window.
public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}
// Displays the UI for value selection.
public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)
{
// Return the value if the value is not of type Int32, Double and Single.
if( value.GetType() != typeof(double) && value.GetType() != typeof(float) && value.GetType() != typeof(int) )
return value;
// Uses the IWindowsFormsEditorService to display a
// drop-down UI in the Properties window.
IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if( edSvc != null )
{
// Display an angle selection control and retrieve the value.
AngleControl angleControl = new AngleControl((double)value);
edSvc.DropDownControl( angleControl );
// Return the value in the appropraite data format.
if( value.GetType() == typeof(double) )
return angleControl.angle;
else if( value.GetType() == typeof(float) )
return (float)angleControl.angle;
else if( value.GetType() == typeof(int) )
return (int)angleControl.angle;
}
return value;
}
// Draws a representation of the property's value.
public override void PaintValue(System.Drawing.Design.PaintValueEventArgs e)
{
int normalX = (e.Bounds.Width/2);
int normalY = (e.Bounds.Height/2);
// Fill background and ellipse and center point.
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);
// Draw line along the current angle.
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 ) ) ) );
}
// Indicates whether the UITypeEditor supports painting a
// representation of a property's value.
public override bool GetPaintValueSupported(System.ComponentModel.ITypeDescriptorContext context)
{
return true;
}
}
// Provides a user interface for adjusting an angle value.
internal class AngleControl : System.Windows.Forms.UserControl
{
// Stores the angle.
public double angle;
// Stores the rotation offset.
private int rotation = 0;
// Control state tracking variables.
private int dbx = -10;
private int dby = -10;
private int overButton = -1;
public AngleControl(double initial_angle)
{
this.angle = initial_angle;
this.SetStyle( ControlStyles.AllPaintingInWmPaint, true );
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
// Set angle origin point at center of control.
int originX = (this.Width/2);
int originY = (this.Height/2);
// Fill background and ellipse and center point.
e.Graphics.FillRectangle(new SolidBrush(Color.DarkBlue), 0, 0, this.Width, this.Height);
e.Graphics.FillEllipse(new SolidBrush(Color.White), 1, 1, this.Width-3, this.Height-3);
e.Graphics.FillEllipse(new SolidBrush(Color.SlateGray), originX-1, originY-1, 3, 3);
// Draw angle markers.
int startangle = (270-rotation)%360;
e.Graphics.DrawString(startangle.ToString(), new Font("Arial", 8), new SolidBrush(Color.DarkGray), (this.Width/2)-10, 10);
startangle = (startangle+90)%360;
e.Graphics.DrawString(startangle.ToString(), new Font("Arial", 8), new SolidBrush(Color.DarkGray), this.Width-18, (this.Height/2)-6);
startangle = (startangle+90)%360;
e.Graphics.DrawString(startangle.ToString(), new Font("Arial", 8), new SolidBrush(Color.DarkGray), (this.Width/2)-6, this.Height-18);
startangle = (startangle+90)%360;
e.Graphics.DrawString(startangle.ToString(), new Font("Arial", 8), new SolidBrush(Color.DarkGray), 10, (this.Height/2)-6);
// Draw line along the current angle.
double radians = ((((angle+rotation)+360)%360)*Math.PI) / (double)180;
e.Graphics.DrawLine( new Pen(new SolidBrush(Color.Red), 1), originX, originY,
originX + (int)( (double)originX * (double)Math.Cos( radians ) ),
originY + (int)( (double)originY * (double)Math.Sin( radians ) ) );
// Output angle information.
e.Graphics.FillRectangle(new SolidBrush(Color.Gray), this.Width-84, 3, 82, 13);
e.Graphics.DrawString("Angle: "+angle.ToString("F4"), new Font("Arial", 8), new SolidBrush(Color.Yellow), this.Width-84, 2);
// Draw square at mouse position of last angle adjustment.
e.Graphics.DrawRectangle(new Pen(new SolidBrush(Color.Black), 1), dbx-2, dby-2, 4, 4);
// Draw rotation adjustment buttons.
if( overButton == 1 )
{
e.Graphics.FillRectangle(new SolidBrush(Color.Green), this.Width-28, this.Height-14, 12, 12);
e.Graphics.FillRectangle(new SolidBrush(Color.Gray), 2, this.Height-13, 110, 12);
e.Graphics.DrawString("Rotate 90 degrees left", new Font("Arial", 8), new SolidBrush(Color.White), 2, this.Height-14);
}
else
e.Graphics.FillRectangle(new SolidBrush(Color.DarkGreen), this.Width-28, this.Height-14, 12, 12);
if( overButton == 2 )
{
e.Graphics.FillRectangle(new SolidBrush(Color.Green), this.Width-14, this.Height-14, 12, 12);
e.Graphics.FillRectangle(new SolidBrush(Color.Gray), 2, this.Height-13, 116, 12);
e.Graphics.DrawString("Rotate 90 degrees right", new Font("Arial", 8), new SolidBrush(Color.White), 2, this.Height-14);
}
else
e.Graphics.FillRectangle(new SolidBrush(Color.DarkGreen), this.Width-14, this.Height-14, 12, 12);
e.Graphics.DrawEllipse(new Pen(new SolidBrush(Color.White), 1), this.Width-11, this.Height-11, 6, 6);
e.Graphics.DrawEllipse(new Pen(new SolidBrush(Color.White), 1), this.Width-25, this.Height-11, 6, 6);
if( overButton == 1 )
e.Graphics.FillRectangle(new SolidBrush(Color.Green), this.Width-25, this.Height-6, 4, 4);
else
e.Graphics.FillRectangle(new SolidBrush(Color.DarkGreen), this.Width-25, this.Height-6, 4, 4);
if( overButton == 2 )
e.Graphics.FillRectangle(new SolidBrush(Color.Green), this.Width-8, this.Height-6, 4, 4);
else
e.Graphics.FillRectangle(new SolidBrush(Color.DarkGreen), this.Width-8, this.Height-6, 4, 4);
e.Graphics.FillPolygon(new SolidBrush(Color.White), new Point[] { new Point(this.Width-7, this.Height-8), new Point(this.Width-3, this.Height-8), new Point(this.Width-5, this.Height-4) });
e.Graphics.FillPolygon(new SolidBrush(Color.White), new Point[] { new Point(this.Width-26, this.Height-8), new Point(this.Width-21, this.Height-8), new Point(this.Width-25, this.Height-4) });
}
protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
{
// Handle rotation adjustment button clicks.
if( e.X >= this.Width-28 && e.X <= this.Width-2 && e.Y >= this.Height-14 && e.Y <= this.Height-2 )
{
if( e.X <= this.Width-16 )
rotation -= 90;
else if( e.X >= this.Width-14 )
rotation += 90;
if( rotation < 0 )
rotation += 360;
rotation = rotation%360;
dbx=-10;
dby=-10;
}
else
UpdateAngle(e.X, e.Y);
this.Refresh();
}
protected override void OnMouseMove(System.Windows.Forms.MouseEventArgs e)
{
if( e.Button == MouseButtons.Left )
{
UpdateAngle(e.X, e.Y);
overButton = -1;
}
else if( e.X >= this.Width-28 && e.X <= this.Width-16 && e.Y >= this.Height-14 && e.Y <= this.Height-2 )
overButton = 1;
else if( e.X >= this.Width-14 && e.X <= this.Width-2 && e.Y >= this.Height-14 && e.Y <= this.Height-2 )
overButton = 2;
else
overButton = -1;
this.Refresh();
}
private void UpdateAngle(int mx, int my)
{
// Store mouse coordinates.
dbx = mx;
dby = my;
// Translate y coordinate input to GetAngle function to correct for ellipsoid distortion.
double widthToHeightRatio = (double)this.Width/(double)this.Height;
int tmy;
if( my == 0 )
tmy = my;
else if( my < this.Height/2 )
tmy = (this.Height/2)-(int)(((this.Height/2)-my)*widthToHeightRatio);
else
tmy = (this.Height/2)+(int)((double)(my-(this.Height/2))*widthToHeightRatio);
// Retrieve updated angle based on rise over run.
angle = (GetAngle(this.Width/2, this.Height/2, mx, tmy)-rotation)%360;
}
private double GetAngle(int x1, int y1, int x2, int y2)
{
double degrees;
// Avoid divide by zero run values.
if( x2-x1 == 0 )
{
if( y2 > y1 )
degrees = 90;
else
degrees = 270;
}
else
{
// Calculate angle from offset.
double riseoverrun = (double)(y2-y1)/(double)(x2-x1);
double radians = Math.Atan( riseoverrun );
degrees = radians * ((double)180/Math.PI);
// Handle quadrant specific transformations.
if( (x2-x1) < 0 || (y2-y1) < 0 )
degrees += 180;
if( (x2-x1) > 0 && (y2-y1) < 0 )
degrees -= 180;
if( degrees < 0 )
degrees += 360;
}
return degrees;
}
}
public class AngleEditorTestControl : System.Windows.Forms.UserControl
{
private double int_angle;
[BrowsableAttribute(true)]
[EditorAttribute(typeof(AngleEditor), typeof(System.Drawing.Design.UITypeEditor))]
public double Angle
{
get
{ return int_angle; }
set
{ int_angle = value; }
}
public AngleEditorTestControl()
{
int_angle = 90;
this.Size = new Size(190, 42);
this.BackColor = Color.Beige;
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
if( this.DesignMode )
{
e.Graphics.DrawString("Use the Properties Window to access", new Font("Arial", 8), new SolidBrush(Color.Black), 3,2);
e.Graphics.DrawString("the AngleEditor UITypeEditor by", new Font("Arial", 8), new SolidBrush(Color.Black), 3,14);
e.Graphics.DrawString("configuring the \"Angle\" property.", new Font("Arial", 8), new SolidBrush(Color.Black), 3,26);
}
else
e.Graphics.DrawString("This example requires design mode.", new Font("Arial", 8), new SolidBrush(Color.Black), 3,2);
}
}
}
#using <System.Windows.Forms.dll>
#using <System.Drawing.dll>
#using <System.dll>
using namespace System;
using namespace System::ComponentModel;
using namespace System::Drawing;
using namespace System::Drawing::Design;
using namespace System::Windows::Forms;
using namespace System::Windows::Forms::Design;
namespace AngleEditor
{
// Provides a user interface for adjusting an angle value.
ref class AngleControl: public System::Windows::Forms::UserControl
{
public:
// Stores the angle.
double angle;
private:
// Stores the rotation offset.
int rotation;
// Control state tracking variables.
int dbx;
int dby;
int overButton;
public:
AngleControl( double initial_angle )
{
this->angle = initial_angle;
this->SetStyle( static_cast<ControlStyles>(ControlStyles::AllPaintingInWmPaint), true );
rotation = 0;
dbx = -10;
dby = -10;
overButton = -1;
}
protected:
virtual void OnPaint( System::Windows::Forms::PaintEventArgs^ e ) override
{
// Set angle origin point at center of control.
int originX = (this->Width / 2);
int originY = (this->Height / 2);
// Fill background and ellipse and center point.
e->Graphics->FillRectangle( gcnew SolidBrush( Color::DarkBlue ), 0, 0, this->Width, this->Height );
e->Graphics->FillEllipse( gcnew SolidBrush( Color::White ), 1, 1, this->Width - 3, this->Height - 3 );
e->Graphics->FillEllipse( gcnew SolidBrush( Color::SlateGray ), originX - 1, originY - 1, 3, 3 );
// Draw angle markers.
int startangle = (270 - rotation) % 360;
e->Graphics->DrawString( startangle.ToString(), gcnew System::Drawing::Font( "Arial",8.0 ), gcnew SolidBrush( Color::DarkGray ), (float)(this->Width / 2) - 10, (float)10 );
startangle = (startangle + 90) % 360;
e->Graphics->DrawString( startangle.ToString(), gcnew System::Drawing::Font( "Arial",8 ), gcnew SolidBrush( Color::DarkGray ), (float)this->Width - 18, (float)(this->Height / 2) - 6 );
startangle = (startangle + 90) % 360;
e->Graphics->DrawString( startangle.ToString(), gcnew System::Drawing::Font( "Arial",8 ), gcnew SolidBrush( Color::DarkGray ), ((float)this->Width / 2) - 6, (float)this->Height - 18 );
startangle = (startangle + 90) % 360;
e->Graphics->DrawString( startangle.ToString(), gcnew System::Drawing::Font( "Arial",8 ), gcnew SolidBrush( Color::DarkGray ), (float)10, (float)(this->Height / 2) - 6 );
// Draw line along the current angle.
double radians = ((((int)(angle + rotation) + 360) % 360) * Math::PI) / (double)180;
e->Graphics->DrawLine( gcnew Pen( gcnew SolidBrush( Color::Red ),1 ), originX, originY, originX + (int)((double)originX * (double)Math::Cos( radians )), originY + (int)((double)originY * (double)Math::Sin( radians )) );
// Output angle information.
e->Graphics->FillRectangle( gcnew SolidBrush( Color::Gray ), this->Width - 84, 3, 82, 13 );
e->Graphics->DrawString( String::Format( "Angle: {0}", angle.ToString( "F4" ) ), gcnew System::Drawing::Font( "Arial",8 ), gcnew SolidBrush( Color::Yellow ), (float)this->Width - 84, (float)2 );
// Draw square at mouse position of last angle adjustment.
e->Graphics->DrawRectangle( gcnew Pen( gcnew SolidBrush( Color::Black ),1 ), dbx - 2, dby - 2, 4, 4 );
// Draw rotation adjustment buttons.
if ( overButton == 1 )
{
e->Graphics->FillRectangle( gcnew SolidBrush( Color::Green ), this->Width - 28, this->Height - 14, 12, 12 );
e->Graphics->FillRectangle( gcnew SolidBrush( Color::Gray ), 2, this->Height - 13, 110, 12 );
e->Graphics->DrawString( "Rotate 90 degrees left", gcnew System::Drawing::Font( "Arial",8 ), gcnew SolidBrush( Color::White ), (float)2, (float)this->Height - 14 );
}
else
e->Graphics->FillRectangle( gcnew SolidBrush( Color::DarkGreen ), this->Width - 28, this->Height - 14, 12, 12 );
if ( overButton == 2 )
{
e->Graphics->FillRectangle( gcnew SolidBrush( Color::Green ), this->Width - 14, this->Height - 14, 12, 12 );
e->Graphics->FillRectangle( gcnew SolidBrush( Color::Gray ), 2, this->Height - 13, 116, 12 );
e->Graphics->DrawString( "Rotate 90 degrees right", gcnew System::Drawing::Font( "Arial",8 ), gcnew SolidBrush( Color::White ), (float)2, (float)this->Height - 14 );
}
else
e->Graphics->FillRectangle( gcnew SolidBrush( Color::DarkGreen ), this->Width - 14, this->Height - 14, 12, 12 );
e->Graphics->DrawEllipse( gcnew Pen( gcnew SolidBrush( Color::White ),1 ), this->Width - 11, this->Height - 11, 6, 6 );
e->Graphics->DrawEllipse( gcnew Pen( gcnew SolidBrush( Color::White ),1 ), this->Width - 25, this->Height - 11, 6, 6 );
if ( overButton == 1 )
e->Graphics->FillRectangle( gcnew SolidBrush( Color::Green ), this->Width - 25, this->Height - 6, 4, 4 );
else
e->Graphics->FillRectangle( gcnew SolidBrush( Color::DarkGreen ), this->Width - 25, this->Height - 6, 4, 4 );
if ( overButton == 2 )
e->Graphics->FillRectangle( gcnew SolidBrush( Color::Green ), this->Width - 8, this->Height - 6, 4, 4 );
else
e->Graphics->FillRectangle( gcnew SolidBrush( Color::DarkGreen ), this->Width - 8, this->Height - 6, 4, 4 );
array<Point>^ temp0 = {Point(this->Width - 7,this->Height - 8),Point(this->Width - 3,this->Height - 8),Point(this->Width - 5,this->Height - 4)};
e->Graphics->FillPolygon( gcnew SolidBrush( Color::White ), temp0 );
array<Point>^ temp1 = {Point(this->Width - 26,this->Height - 8),Point(this->Width - 21,this->Height - 8),Point(this->Width - 25,this->Height - 4)};
e->Graphics->FillPolygon( gcnew SolidBrush( Color::White ), temp1 );
}
virtual void OnMouseDown( System::Windows::Forms::MouseEventArgs^ e ) override
{
// Handle rotation adjustment button clicks.
if ( e->X >= this->Width - 28 && e->X <= this->Width - 2 && e->Y >= this->Height - 14 && e->Y <= this->Height - 2 )
{
if ( e->X <= this->Width - 16 )
rotation -= 90;
else
if ( e->X >= this->Width - 14 )
rotation += 90;
if ( rotation < 0 )
rotation += 360;
rotation = rotation % 360;
dbx = -10;
dby = -10;
}
else
UpdateAngle( e->X, e->Y );
this->Refresh();
}
virtual void OnMouseMove( System::Windows::Forms::MouseEventArgs^ e ) override
{
if ( e->Button == ::MouseButtons::Left )
{
UpdateAngle( e->X, e->Y );
overButton = -1;
}
else
if ( e->X >= this->Width - 28 && e->X <= this->Width - 16 && e->Y >= this->Height - 14 && e->Y <= this->Height - 2 )
overButton = 1;
else
if ( e->X >= this->Width - 14 && e->X <= this->Width - 2 && e->Y >= this->Height - 14 && e->Y <= this->Height - 2 )
overButton = 2;
else
overButton = -1;
this->Refresh();
}
private:
void UpdateAngle( int mx, int my )
{
// Store mouse coordinates.
dbx = mx;
dby = my;
// Translate y coordinate input to GetAngle function to correct for ellipsoid distortion.
double widthToHeightRatio = (double)this->Width / (double)this->Height;
int tmy;
if ( my == 0 )
tmy = my;
else
if ( my < this->Height / 2 )
tmy = (this->Height / 2) - (int)(((this->Height / 2) - my) * widthToHeightRatio);
else
tmy = (this->Height / 2) + (int)((double)(my - (this->Height / 2)) * widthToHeightRatio);
// Retrieve updated angle based on rise over run.
angle = (int)(GetAngle( this->Width / 2, this->Height / 2, mx, tmy ) - rotation) % 360;
}
double GetAngle( int x1, int y1, int x2, int y2 )
{
double degrees;
// Avoid divide by zero run values.
if ( x2 - x1 == 0 )
{
if ( y2 > y1 )
degrees = 90;
else
degrees = 270;
}
else
{
// Calculate angle from offset.
double riseoverrun = (double)(y2 - y1) / (double)(x2 - x1);
double radians = Math::Atan( riseoverrun );
degrees = radians * ((double)180 / Math::PI);
// Handle quadrant specific transformations.
if ( (x2 - x1) < 0 || (y2 - y1) < 0 )
degrees += 180;
if ( (x2 - x1) > 0 && (y2 - y1) < 0 )
degrees -= 180;
if ( degrees < 0 )
degrees += 360;
}
return degrees;
}
};
// This UITypeEditor can be associated with Int32, Double and Single
// properties to provide a design-mode angle selection interface.
[System::Security::Permissions::PermissionSetAttribute
(System::Security::Permissions::SecurityAction::InheritanceDemand, Name="FullTrust")]
[System::Security::Permissions::PermissionSetAttribute
(System::Security::Permissions::SecurityAction::LinkDemand, Name="FullTrust")]
public ref class AngleEditor: public System::Drawing::Design::UITypeEditor
{
public:
AngleEditor(){}
// Indicates whether the UITypeEditor provides a form-based (modal) dialog,
// drop down dialog, or no UI outside of the properties window.
virtual System::Drawing::Design::UITypeEditorEditStyle GetEditStyle( System::ComponentModel::ITypeDescriptorContext^ context ) override
{
return UITypeEditorEditStyle::DropDown;
}
// Displays the UI for value selection.
virtual Object^ EditValue( System::ComponentModel::ITypeDescriptorContext^ context, System::IServiceProvider^ provider, Object^ value ) override
{
// Return the value if the value is not of type Int32, Double and Single.
if ( value->GetType() != double::typeid && value->GetType() != float::typeid && value->GetType() != int::typeid )
return value;
// Uses the IWindowsFormsEditorService* to display a
// drop-down UI in the Properties window.
IWindowsFormsEditorService^ edSvc = dynamic_cast<IWindowsFormsEditorService^>(provider->GetService( IWindowsFormsEditorService::typeid ));
if ( edSvc != nullptr )
{
// Display an angle selection control and retrieve the value.
AngleControl^ angleControl = gcnew AngleControl( *dynamic_cast<double^>(value) );
edSvc->DropDownControl( angleControl );
// Return the value in the appropraite data format.
if ( value->GetType() == double::typeid )
return angleControl->angle;
else
if ( value->GetType() == float::typeid )
return (float)angleControl->angle;
else
if ( value->GetType() == int::typeid )
return (int)angleControl->angle;
}
return value;
}
// Draws a representation of the property's value.
private:
void PaintValue( System::Drawing::Design::PaintValueEventArgs^ e ) new
{
int normalX = (e->Bounds.Width / 2);
int normalY = (e->Bounds.Height / 2);
// Fill background and ellipse and center point.
e->Graphics->FillRectangle( gcnew SolidBrush( Color::DarkBlue ), e->Bounds.X, e->Bounds.Y, e->Bounds.Width, e->Bounds.Height );
e->Graphics->FillEllipse( gcnew SolidBrush( Color::White ), e->Bounds.X + 1, e->Bounds.Y + 1, e->Bounds.Width - 3, e->Bounds.Height - 3 );
e->Graphics->FillEllipse( gcnew SolidBrush( Color::SlateGray ), normalX + e->Bounds.X - 1, normalY + e->Bounds.Y - 1, 3, 3 );
// Draw line along the current angle.
double radians = ( *dynamic_cast<double^>(e->Value) * Math::PI) / (double)180;
e->Graphics->DrawLine( gcnew Pen( gcnew 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 ))) );
}
// Indicates whether the UITypeEditor supports painting a
// representation of a property's value.
bool GetPaintValueSupported( System::ComponentModel::ITypeDescriptorContext^ context ) new
{
return true;
}
};
public ref class AngleEditorTestControl: public System::Windows::Forms::UserControl
{
private:
double int_angle;
public:
property double Angle
{
[BrowsableAttribute(true)]
[EditorAttribute(AngleEditor::typeid,System::Drawing::Design::UITypeEditor::typeid)]
double get()
{
return int_angle;
}
void set( double value )
{
int_angle = value;
}
}
AngleEditorTestControl()
{
int_angle = 90;
this->Size = System::Drawing::Size( 190, 42 );
this->BackColor = Color::Beige;
}
protected:
virtual void OnPaint( System::Windows::Forms::PaintEventArgs^ e ) override
{
if ( this->DesignMode )
{
e->Graphics->DrawString( "Use the Properties Window to access",
gcnew System::Drawing::Font( "Arial",8 ), gcnew SolidBrush( Color::Black ), 3, 2 );
e->Graphics->DrawString( "the AngleEditor UITypeEditor by",
gcnew System::Drawing::Font( "Arial",8 ), gcnew SolidBrush( Color::Black ), 3, 14 );
e->Graphics->DrawString( "configuring the \"Angle\" property.",
gcnew System::Drawing::Font( "Arial",8 ), gcnew SolidBrush( Color::Black ), 3, 26 );
}
else
e->Graphics->DrawString( "This example requires design mode.",
gcnew System::Drawing::Font( "Arial",8 ), gcnew SolidBrush( Color::Black ), 3, 2 );
}
};
}
package AngleEditor;
import System.*;
import System.ComponentModel.*;
import System.Drawing.*;
import System.Drawing.Design.*;
import System.Windows.Forms.*;
import System.Windows.Forms.Design.*;
import System.Security.Permissions.*;
// This UITypeEditor can be associated with Int32, Double and Single
// properties to provide a design-mode angle selection interface.
/** @attribute PermissionSet(SecurityAction.Demand, Name = "FullTrust")
*/
public class AngleEditor extends System.Drawing.Design.UITypeEditor
{
public AngleEditor()
{
} //AngleEditor
// Indicates whether the UITypeEditor provides a form-based (modal)
// dialog, drop down dialog, or no UI outside of the properties window.
public System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(
System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
} //GetEditStyle
// Displays the UI for value selection.
public Object EditValue(System.ComponentModel.ITypeDescriptorContext
context, System.IServiceProvider provider, Object value)
{
// Return the value if the value is not of type Int32, Double
// and Single.
if (!value.GetType().Equals(double.class.ToType())
&& !value.GetType().Equals(float.class.ToType())
&& !value.GetType().Equals(int.class.ToType())) {
return value;
}
// Uses the IWindowsFormsEditorService to display a
// drop-down UI in the Properties window.
IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)
provider.GetService(IWindowsFormsEditorService.class.ToType());
if (edSvc != null) {
// Display an angle selection control and retrieve the value.
AngleControl angleControl =
new AngleControl(Convert.ToDouble(value));
edSvc.DropDownControl(angleControl);
// Return the value in the appropraite data format.
if (value.GetType().Equals(double.class.ToType())) {
return (System.Double)(angleControl.angle);
}
else {
if (value.GetType().Equals(float.class.ToType())) {
return (System.Single)(angleControl.angle);
}
else {
if (value.GetType().Equals(int.class.ToType())) {
return (Int32)(angleControl.angle);
}
}
}
}
return value;
} //EditValue
// Draws a representation of the property's value.
public void PaintValue(System.Drawing.Design.PaintValueEventArgs e)
{
int normalX = e.get_Bounds().get_Width() / 2;
int normalY = e.get_Bounds().get_Height() / 2;
// Fill background and ellipse and center point.
e.get_Graphics().FillRectangle(new SolidBrush(Color.get_DarkBlue()),
e.get_Bounds().get_X(), e.get_Bounds().get_Y(),
e.get_Bounds().get_Width(), e.get_Bounds().get_Height());
e.get_Graphics().FillEllipse(new SolidBrush(Color.get_White()),
e.get_Bounds().get_X() + 1, e.get_Bounds().get_Y() + 1,
e.get_Bounds().get_Width() - 3, e.get_Bounds().get_Height() - 3);
e.get_Graphics().FillEllipse(new SolidBrush(Color.get_SlateGray()),
normalX + e.get_Bounds().get_X() - 1,
normalY + e.get_Bounds().get_Y() - 1, 3, 3);
// Draw line along the current angle.
double radians = (double)(System.Double)(e.get_Value())
* System.Math.PI / (double)(180);
e.get_Graphics().DrawLine(new Pen(new SolidBrush(Color.get_Red()), 1),
normalX + e.get_Bounds().get_X(),
normalY + e.get_Bounds().get_Y(),
e.get_Bounds().get_X()
+ (normalX + (int)((double)(normalX) * System.Math.Cos(radians))),
e.get_Bounds().get_Y()
+ (normalY + (int)((double)(normalY) * System.Math.Sin(radians))));
} //PaintValue
// Indicates whether the UITypeEditor supports painting a
// representation of a property's value.
public boolean GetPaintValueSupported(
System.ComponentModel.ITypeDescriptorContext context)
{
return true;
} //GetPaintValueSupported
} //AngleEditor
// Provides a user interface for adjusting an angle value.
class AngleControl extends System.Windows.Forms.UserControl
{
// Stores the angle.
public double angle;
// Stores the rotation offset.
private int rotation = 0;
// Control state tracking variables.
private int dbX = -10;
private int dbY = -10;
private int overButton = -1;
public AngleControl(double initialAngle)
{
this.angle = initialAngle;
this.SetStyle(ControlStyles.OptimizedDoubleBuffer
| ControlStyles.AllPaintingInWmPaint, true);
} //AngleControl
protected void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
// Set angle origin point at center of control.
int originX = this.get_Width() / 2;
int originY = this.get_Height() / 2;
// Fill background and ellipse and center point.
e.get_Graphics().FillRectangle(new SolidBrush(Color.get_DarkBlue()),
0, 0, this.get_Width(), this.get_Height());
e.get_Graphics().FillEllipse(new SolidBrush(Color.get_White()), 1, 1,
this.get_Width() - 3, this.get_Height() - 3);
e.get_Graphics().FillEllipse(new SolidBrush(Color.get_SlateGray()),
originX - 1, originY - 1, 3, 3);
// Draw angle markers.
int startAngle = (270 - rotation) % 360;
e.get_Graphics().DrawString(System.Convert.ToString(startAngle),
new Font("Arial", 8), new SolidBrush(Color.get_DarkGray()),
this.get_Width() / 2 - 10, 10);
startAngle = (startAngle + 90) % 360;
e.get_Graphics().DrawString(System.Convert.ToString(startAngle),
new Font("Arial", 8), new SolidBrush(Color.get_DarkGray()),
this.get_Width() - 18, this.get_Height() / 2 - 6);
startAngle = (startAngle + 90) % 360;
e.get_Graphics().DrawString(System.Convert.ToString(startAngle),
new Font("Arial", 8), new SolidBrush(Color.get_DarkGray()),
this.get_Width() / 2 - 6, this.get_Height() - 18);
startAngle = (startAngle + 90) % 360;
e.get_Graphics().DrawString(System.Convert.ToString(startAngle),
new Font("Arial", 8), new SolidBrush(Color.get_DarkGray()), 10,
this.get_Height() / 2 - 6);
// Draw line along the current angle.
double radians = ((angle + rotation + 360) % 360) * System.Math.PI
/ (double)180;
e.get_Graphics().DrawLine(new Pen(new SolidBrush(Color.get_Red()), 1),
originX, originY,
originX + (int)((double)(originX) * (double)
(System.Math.Cos(radians))), originY + (int)((double)(originY)
* (double)(System.Math.Sin(radians))));
// Output angle information.
e.get_Graphics().FillRectangle(new SolidBrush(Color.get_Gray()),
this.get_Width() - 84, 3, 82, 13);
e.get_Graphics().DrawString("Angle: " + System.Convert.ToString(angle),
new Font("Arial", 8), new SolidBrush(Color.get_Yellow()),
this.get_Width() - 84, 2);
// Draw square at mouse position of last angle adjustment.
e.get_Graphics().DrawRectangle(new Pen(new SolidBrush(
Color.get_Black()), 1), dbX - 2, dbY - 2, 4, 4);
// Draw rotation adjustment buttons.
if (overButton == 1) {
e.get_Graphics().FillRectangle(new SolidBrush(Color.get_Green()),
this.get_Width() - 28, this.get_Height() - 14, 12, 12);
e.get_Graphics().FillRectangle(new SolidBrush(Color.get_Gray()), 2,
this.get_Height() - 13, 110, 12);
e.get_Graphics().DrawString("Rotate 90 degrees left",
new Font("Arial", 8), new SolidBrush(Color.get_White()), 2,
this.get_Height() - 14);
}
else {
e.get_Graphics().FillRectangle(
new SolidBrush(Color.get_DarkGreen()),
this.get_Width() - 28, this.get_Height() - 14, 12, 12);
}
if (overButton == 2) {
e.get_Graphics().FillRectangle(new SolidBrush(Color.get_Green()),
this.get_Width() - 14, this.get_Height() - 14, 12, 12);
e.get_Graphics().FillRectangle(new SolidBrush(Color.get_Gray()), 2,
this.get_Height() - 13, 116, 12);
e.get_Graphics().DrawString("Rotate 90 degrees right",
new Font("Arial", 8), new SolidBrush(Color.get_White()), 2,
this.get_Height() - 14);
}
else {
e.get_Graphics().FillRectangle(
new SolidBrush(Color.get_DarkGreen()),
this.get_Width() - 14, this.get_Height() - 14, 12, 12);
}
e.get_Graphics().DrawEllipse(new Pen(new SolidBrush(Color.get_White()),
1), this.get_Width() - 11, this.get_Height() - 11, 6, 6);
e.get_Graphics().DrawEllipse(new Pen(new SolidBrush(Color.get_White()),
1), this.get_Width() - 25, this.get_Height() - 11, 6, 6);
if (overButton == 1) {
e.get_Graphics().FillRectangle(new SolidBrush(Color.get_Green()),
this.get_Width() - 25, this.get_Height() - 6, 4, 4);
}
else {
e.get_Graphics().FillRectangle(new SolidBrush(Color.get_DarkGreen()),
this.get_Width() - 25, this.get_Height() - 6, 4, 4);
}
if (overButton == 2) {
e.get_Graphics().FillRectangle(new SolidBrush(Color.get_Green()),
this.get_Width() - 8, this.get_Height() - 6, 4, 4);
}
else {
e.get_Graphics().FillRectangle(new SolidBrush(Color.get_DarkGreen()),
this.get_Width() - 8, this.get_Height() - 6, 4, 4);
}
e.get_Graphics().FillPolygon(new SolidBrush(Color.get_White()),
new Point[] {
new Point(this.get_Width() - 7, this.get_Height() - 8),
new Point(this.get_Width() - 3, this.get_Height() - 8),
new Point(this.get_Width() - 5, this.get_Height() - 4) });
e.get_Graphics().FillPolygon(new SolidBrush(Color.get_White()),
new Point[] {
new Point(this.get_Width() - 26, this.get_Height() - 8),
new Point(this.get_Width() - 21, this.get_Height() - 8),
new Point(this.get_Width() - 25, this.get_Height() - 4) });
} //OnPaint
protected void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
{
// Handle rotation adjustment button clicks.
if (e.get_X() >= this.get_Width() - 28
&& e.get_X() <= this.get_Width() - 2
&& e.get_Y() >= this.get_Height() - 14
&& e.get_Y() <= this.get_Height() - 2) {
if (e.get_X() <= this.get_Width() - 16) {
rotation -= 90;
}
else {
if (e.get_X() >= this.get_Width() - 14) {
rotation += 90;
}
}
if (rotation < 0) {
rotation += 360;
}
rotation = rotation % 360;
dbX = -10;
dbY = -10;
}
else {
UpdateAngle(e.get_X(), e.get_Y());
}
this.Refresh();
} //OnMouseDown
protected void OnMouseMove(System.Windows.Forms.MouseEventArgs e)
{
if (e.get_Button().Equals(MouseButtons.Left)) {
UpdateAngle(e.get_X(), e.get_Y());
overButton = -1;
}
else {
if (e.get_X() >= this.get_Width() - 28
&& e.get_X() <= this.get_Width() - 16
&& e.get_Y() >= this.get_Height() - 14
&& e.get_Y() <= this.get_Height() - 2) {
overButton = 1;
}
else {
if (e.get_X() >= this.get_Width() - 14
&& e.get_X() <= this.get_Width() - 2
&& e.get_Y() >= this.get_Height() - 14
&& e.get_Y() <= this.get_Height() - 2) {
overButton = 2;
}
else {
overButton = -1;
}
}
}
this.Refresh();
} //OnMouseMove
private void UpdateAngle(int mX, int mY)
{
// Store mouse coordinates.
dbX = mX;
dbY = mY;
// Translate y coordinate input to GetAngle function to correct for
// ellipsoid distortion.
double widthToHeightRatio =
(double)(this.get_Width()) / (double)(this.get_Height());
int tmY;
if (mY == 0) {
tmY = mY;
}
else {
if (mY < this.get_Height() / 2) {
tmY = this.get_Height() / 2
- (int)((this.get_Height() / 2 - mY) * widthToHeightRatio);
}
else {
tmY = this.get_Height() / 2 + (int)((double)
(mY - this.get_Height() / 2) * widthToHeightRatio);
}
}
// Retrieve updated angle based on rise over run.
angle = (GetAngle(this.get_Width() / 2, this.get_Height() / 2, mX,
tmY) - rotation) % 360;
} //UpdateAngle
private double GetAngle(int x1, int y1, int x2, int y2)
{
double degrees;
// Avoid divide by zero run values.
if (x2 - x1 == 0) {
if (y2 > y1) {
degrees = 90;
}
else {
degrees = 270;
}
}
else {
// Calculate angle from offset.
double riseOverRun = (double)(y2 - y1) / (double)(x2 - x1);
double radians = System.Math.Atan(riseOverRun);
degrees = radians * (double)(180) / System.Math.PI;
// Handle quadrant specific transformations.
if (x2 - x1 < 0 || y2 - y1 < 0) {
degrees += 180;
}
if (x2 - x1 > 0 && y2 - y1 < 0) {
degrees -= 180;
}
if (degrees < 0) {
degrees += 360;
}
}
return degrees;
} //GetAngle
} //AngleControl
public class AngleEditorTestControl extends System.Windows.Forms.UserControl
{
private double intAngle;
/** @attribute BrowsableAttribute(true)
*/
/** @attribute EditorAttribute(AngleEditor.class,
System.Drawing.Design.UITypeEditor.class)
*/
/** @property
*/
public double get_Angle()
{
return intAngle;
} //get_Angle
/** @property
*/
public void set_Angle(double value)
{
intAngle = value;
} //set_Angle
public AngleEditorTestControl()
{
intAngle = 90;
this.set_Size(new Size(190, 42));
this.set_BackColor(Color.get_Beige());
} //AngleEditorTestControl
protected void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
if (this.get_DesignMode()) {
e.get_Graphics().DrawString("Use the Properties Window to access",
new Font("Arial", 8), new SolidBrush(Color.get_Black()), 3, 2);
e.get_Graphics().DrawString("the AngleEditor UITypeEditor by",
new Font("Arial", 8), new SolidBrush(Color.get_Black()), 3, 14);
e.get_Graphics().DrawString("configuring the \"Angle\" property.",
new Font("Arial", 8), new SolidBrush(Color.get_Black()), 3, 26);
}
else {
e.get_Graphics().DrawString("This example requires design mode.",
new Font("Arial", 8), new SolidBrush(Color.get_Black()), 3, 2);
}
} //OnPaint
} //AngleEditorTestControl
.NET Framework 安全性
- NamedPermissionSet 用于对系统资源进行完全访问。要求值:LinkDemand、InheritanceDemand。关联状态:FullTrust
继承层次结构
System.Object
System.Drawing.Design.UITypeEditor
派生类
线程安全
此类型的任何公共静态(Visual Basic 中的 Shared)成员都是线程安全的,但不保证所有实例成员都是线程安全的。
平台
Windows 98、Windows 2000 SP4、Windows Millennium Edition、Windows Server 2003、Windows XP Media Center Edition、Windows XP Professional x64 Edition、Windows XP SP2、Windows XP Starter Edition
.NET Framework 并不是对每个平台的所有版本都提供支持。有关受支持版本的列表,请参见系统要求。
版本信息
.NET Framework
受以下版本支持:2.0、1.1、1.0
请参见
参考
UITypeEditor 成员
System.Drawing.Design 命名空间
ITypeDescriptorContext
IServiceProvider