UITypeEditor クラスとは? わかりやすく解説

UITypeEditor クラス

エディタデザインするために使用できる基本クラス提供します。値エディタは、サポートされているデータ型オブジェクトの値を表示および編集するためのユーザー インターフェイス (UI) を提供します

名前空間: System.Drawing.Design
アセンブリ: System.Drawing (system.drawing.dll 内)
構文構文

public class UITypeEditor
public ref class UITypeEditor
public class UITypeEditor
public class UITypeEditor
解説解説

UITypeEditor クラス提供される基本クラスから派生したクラス拡張することによって、デザイン時の環境合わせたカスタムエディタ実装できますカスタムエディタは、テキスト ボックスの値エディタでは特定の型の値を効率よく選択できないような場合役立ちます

デザイン時に使用するカスタムUIエディタ実装するには、次の手順を行う必要があります

また、次の手順実行することにより、値の視覚的な表現を [プロパティ] ウィンドウ描画する機能追加できます

メモメモ

UITypeEditor クラスは、右から左 (RTL) へのレイアウトサポートしていません。

デザイン時のサポート拡張方法については、「デザインサポート拡張」を参照してください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
.NET Framework のセキュリティ.NET Frameworkセキュリティ
継承階層継承階層
System.Object
  System.Drawing.Design.UITypeEditor
     派生クラス
スレッド セーフスレッド セーフ
この型の public static (Visual Basic では Shared) メンバはすべて、スレッド セーフです。インスタンス メンバ場合は、スレッド セーフであるとは限りません。
プラットフォームプラットフォーム
バージョン情報バージョン情報
参照参照
関連項目
UITypeEditor メンバ
System.Drawing.Design 名前空間
ITypeDescriptorContext
IServiceProvider
その他の技術情報
ユーザー インターフェイスエディタ概要
方法 : UIエディタ実装する



英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「UITypeEditor クラス」の関連用語

UITypeEditor クラスのお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



UITypeEditor クラスのページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
日本マイクロソフト株式会社日本マイクロソフト株式会社
© 2024 Microsoft.All rights reserved.

©2024 GRAS Group, Inc.RSS