UITypeEditor クラス
アセンブリ: System.Drawing (system.drawing.dll 内)
構文
解説
UITypeEditor クラスで提供される基本クラスから派生したクラスを拡張することによって、デザイン時の環境に合わせたカスタム型エディタを実装できます。カスタム型エディタは、テキスト ボックスの値エディタでは特定の型の値を効率よく選択できないような場合に役立ちます。
デザイン時に使用するカスタムの UI 型エディタを実装するには、次の手順を行う必要があります。
-
EditValue メソッドをオーバーライドし、ユーザー インターフェイス、ユーザーによる入力、および値の代入を処理できるようにします。
-
GetEditStyle メソッドをオーバーライドし、エディタが使用するエディタ スタイルの型をプロパティ ウィンドウに通知するようにします。
また、次の手順を実行することにより、値の視覚的な表現を [プロパティ] ウィンドウに描画する機能を追加できます。
メモ |
---|
デザイン時のサポートの拡張方法については、「デザイン時サポートの拡張」を参照してください。UITypeEditor の実装の詳細については、「ユーザー インターフェイス型エディタの概要」を参照してください。
デザイン モードの [プロパティ] ウィンドウから角度選択インターフェイスを提供するために、EditorAttribute を使用して、UITypeEditor を整数、倍精度浮動小数点数、または浮動小数点プロパティに関連付けるコード例を次に示します。この例は、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
スレッド セーフ
プラットフォーム
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 によってサポートされていないバージョンがあります。サポートされているバージョンについては、「システム要件」を参照してください。
参照
- UITypeEditor クラスのページへのリンク