UITypeEditor 클래스
정의
값 편집기를 디자인하는 데 사용할 수 있는 기본 클래스를 제공합니다. 값 편집기는 지원되는 데이터 형식 개체의 값을 나타내고 편집할 수 있는 사용자 인터페이스를 제공합니다.Provides a base class that can be used to design value editors that can provide a user interface (UI) for representing and editing the values of objects of the supported data types.
public ref class UITypeEditor
public class UITypeEditor
type UITypeEditor = class
Public Class UITypeEditor
- 상속
-
UITypeEditor
- 파생
예제
다음 코드 예제에서는를 UITypeEditor 사용 하 여 EditorAttribute 속성 창에서 디자인 모드의 각도 선택 인터페이스를 제공 하는 정수, double 또는 float 속성과 연결할 수 있음을 보여 줍니다.The following code example demonstrates that a UITypeEditor can be associated with an integer, double, or float property using an EditorAttribute to provide an angle selection interface from the Properties window in design mode. 이 예제에서는 인터페이스를 사용 하 여 IWindowsFormsEditorService 속성 창 디자인 모드의 드롭다운 컨트롤을 표시 합니다.This example uses the IWindowsFormsEditorService interface to display a drop-down control in the Properties window in design mode. Visual Studio의 도구 메뉴에서 도구 상자 사용자 지정 명령을 사용 하 여 코드를 컴파일하고 어셈블리를 도구 상자에 추가 합니다.Compile the code and add the assembly to the Toolbox using the Customize Toolbox command on the Tools menu of Visual Studio. 의 인스턴스를 만들고 AngleTestControl
속성 창의 각도 속성 옆에 있는 드롭다운 단추를 클릭 하 여 편집기를 사용 하 여 속성을 구성 합니다.Create an instance of the AngleTestControl
and click the drop-down button next to the Angle property in the Properties window to configure the property using the editor.
#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 );
}
};
}
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);
}
}
}
}
Option Strict Off
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 value.GetType() IsNot GetType(Double) AndAlso value.GetType() IsNot GetType(Single) AndAlso value.GetType() IsNot 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 (edSvc IsNot 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
설명
UITypeEditor클래스는 파생 시킬 수 있는 기본 클래스를 제공 하 고, 디자인 타임 환경에 대 한 사용자 지정 형식 편집기를 구현 하기 위해를 확장할 수 있습니다.The UITypeEditor class provides a base class that you can derive from and extend to implement a custom type editor for the design-time environment. 일반적으로 사용자 지정 형식 편집기는 컨트롤과 상호 작용 PropertyGrid 합니다.Typically, your custom type editor interacts with the PropertyGrid control.
사용자 지정 형식 편집기는 텍스트 상자 값 편집기에서 특정 형식의 값을 효과적으로 선택 하는 데 충분 하지 않은 경우에 유용 합니다.Custom type editors are useful in situations where a text-box value editor is insufficient to effectively select the values of certain types.
사용자 지정 디자인 타임 UI 형식 편집기를 구현 하려면 다음 단계를 수행 해야 합니다.To implement a custom design-time UI type editor, you must perform the following steps:
UITypeEditor에서 파생된 클래스를 정의합니다.Define a class that derives from UITypeEditor.
메서드를 재정의 EditValue 하 여 사용자 인터페이스, 사용자 입력 처리 및 값 할당을 처리 합니다.Override the EditValue method to handle the user interface, user input processing, and value assignment.
GetEditStyle편집기에서 사용할 편집기 스타일의 유형을 속성 창에 알리기 위해 메서드를 재정의 합니다.Override the GetEditStyle method to inform the Properties window of the type of editor style that the editor will use.
다음 단계를 수행 하 여 속성 창에서 값 표시를 그리기 위한 추가 지원을 추가할 수 있습니다.You can add additional support for painting a value's representation in the Properties window by performing the following steps:
메서드를 재정의 GetPaintValueSupported 하 여 편집기에서 값 표현의 표시를 지원함을 나타냅니다.Override the GetPaintValueSupported method to indicate that the editor supports displaying the value's representation.
PaintValue값 표현의 표시를 구현 하려면 메서드를 재정의 합니다.Override the PaintValue method to implement the display of the value's representation.
UITypeEditor편집기에서 초기화 동작을 포함 해야 하는 경우 생성자 메서드를 재정의 합니다.Override the UITypeEditor constructor method if the editor should have initialization behavior.
참고
UITypeEditor클래스에서 RTL (오른쪽에서 왼쪽) 레이아웃을 지원 하지 않습니다.The UITypeEditor class does not support right-to-left (RTL) layouts.
디자인 타임 지원 기능을 개선 하는 방법에 대 한 자세한 내용은 디자인 타임 지원 확장을 참조 하세요.For more information about enhancing design-time support, see Extending Design-Time Support. 구현에 대 한 자세한 내용은 UITypeEditor 사용자 인터페이스 형식 편집기 개요를 참조 하세요.For more information on implementing a UITypeEditor, see User Interface Type Editors Overview.
생성자
UITypeEditor() |
UITypeEditor 클래스의 새 인스턴스를 초기화합니다.Initializes a new instance of the UITypeEditor class. |
속성
IsDropDownResizable |
드롭다운 편집기를 사용자가 크기 조정할 수 있는지 여부를 나타내는 값을 가져옵니다.Gets a value indicating whether drop-down editors should be resizable by the user. |
메서드
EditValue(IServiceProvider, Object) |
GetEditStyle() 메서드에 표시된 편집기 스타일을 사용하여 지정된 개체의 값을 편집합니다.Edits the value of the specified object using the editor style indicated by the GetEditStyle() method. |
EditValue(ITypeDescriptorContext, IServiceProvider, Object) |
GetEditStyle() 메서드에 표시된 편집기 스타일을 사용하여 지정된 개체의 값을 편집합니다.Edits the specified object's value using the editor style indicated by the GetEditStyle() method. |
Equals(Object) |
지정된 개체가 현재 개체와 같은지 확인합니다.Determines whether the specified object is equal to the current object. (다음에서 상속됨 Object) |
GetEditStyle() |
EditValue(IServiceProvider, Object) 메서드에서 사용하는 편집기 스타일을 가져옵니다.Gets the editor style used by the EditValue(IServiceProvider, Object) method. |
GetEditStyle(ITypeDescriptorContext) |
EditValue(IServiceProvider, Object) 메서드에서 사용하는 편집기 스타일을 가져옵니다.Gets the editor style used by the EditValue(IServiceProvider, Object) method. |
GetHashCode() |
기본 해시 함수로 작동합니다.Serves as the default hash function. (다음에서 상속됨 Object) |
GetPaintValueSupported() |
이 편집기에서 개체 값 표현를 칠할 수 있는지 여부를 나타냅니다.Indicates whether this editor supports painting a representation of an object's value. |
GetPaintValueSupported(ITypeDescriptorContext) |
지정된 컨텍스트에서 지정된 컨텍스트 내의 개체 값 표현를 칠할 수 있는지 여부를 나타냅니다.Indicates whether the specified context supports painting a representation of an object's value within the specified context. |
GetType() |
현재 인스턴스의 Type을 가져옵니다.Gets the Type of the current instance. (다음에서 상속됨 Object) |
MemberwiseClone() |
현재 Object의 단순 복사본을 만듭니다.Creates a shallow copy of the current Object. (다음에서 상속됨 Object) |
PaintValue(Object, Graphics, Rectangle) |
지정된 개체의 값 표시를 지정된 캔버스에 칠합니다.Paints a representation of the value of the specified object to the specified canvas. |
PaintValue(PaintValueEventArgs) |
지정된 PaintValueEventArgs를 사용하여 개체 값 표현를 칠합니다.Paints a representation of the value of an object using the specified PaintValueEventArgs. |
ToString() |
현재 개체를 나타내는 문자열을 반환합니다.Returns a string that represents the current object. (다음에서 상속됨 Object) |