Прочитать на английском

Поделиться через


UITypeEditor Класс

Определение

Предоставляет базовый класс, используемый для конструирования редакторов значений, которые обеспечивают пользовательский интерфейс для визуализации и редактирования значений объектов поддерживаемых типов данных.

C#
public class UITypeEditor
Наследование
UITypeEditor
Производный

Примеры

В следующем примере кода показано, что UITypeEditor можно связать со свойством integer, double или float, используя EditorAttribute для предоставления интерфейса выбора угла из окна Свойства в режиме конструктора. В этом примере интерфейс используется IWindowsFormsEditorService для отображения раскрывающегося списка в окне Свойства в режиме конструктора. Скомпилируйте код и добавьте сборку на панель элементов с помощью команды Настроить панель элементов в меню Сервис Visual Studio. Создайте экземпляр AngleTestControl и нажмите кнопку раскрывающегося списка рядом со свойством Angle в окне Свойства, чтобы настроить свойство с помощью редактора.

C#
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.
    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);
            }
        }
    }
}

Комментарии

Класс UITypeEditor предоставляет базовый класс, который можно наследовать от и расширить для реализации пользовательского редактора типов для среды времени разработки. Как правило, пользовательский редактор типов взаимодействует с элементом PropertyGrid управления .

Пользовательские редакторы типов полезны в ситуациях, когда редактора значений текстового поля недостаточно для эффективного выбора значений определенных типов.

Чтобы реализовать пользовательский редактор типов пользовательского интерфейса во время разработки, необходимо выполнить следующие действия.

  • Определите класс, производный от класса UITypeEditor.

  • Переопределите EditValue метод для обработки пользовательского интерфейса, обработки ввода пользователем и назначения значений.

  • Переопределите метод , GetEditStyle чтобы сообщить окну Свойства тип стиля редактора, который будет использоваться редактором.

Вы можете добавить дополнительную поддержку для рисования представления значения в окне Свойства, выполнив следующие действия.

  • Переопределите метод , GetPaintValueSupported чтобы указать, что редактор поддерживает отображение представления значения.

  • Переопределите PaintValue метод , чтобы реализовать отображение представления значения.

  • Переопределите метод конструктора, UITypeEditor если редактор должен иметь поведение инициализации.

Примечание

Класс UITypeEditor не поддерживает макеты справа налево (RTL).

Дополнительные сведения об улучшении поддержки во время разработки см. в разделе Расширение поддержки Design-Time. Дополнительные сведения о реализации см. в статье Общие сведения о редакторах типов пользовательскогоUITypeEditor интерфейса.

Конструкторы

UITypeEditor()

Инициализирует новый экземпляр класса UITypeEditor.

Свойства

IsDropDownResizable

Возвращает значение, указывающее, должен ли пользователь иметь возможность изменять размер редакторов с раскрывающимися списками.

Методы

EditValue(IServiceProvider, Object)

Изменяет значение заданного объекта, используя стиль редактирования, определенного при помощи метода GetEditStyle().

EditValue(ITypeDescriptorContext, IServiceProvider, Object)

Изменяет значение указанного объекта, используя стиль редактирования, определенный с помощью метода GetEditStyle().

Equals(Object)

Определяет, равен ли указанный объект текущему объекту.

(Унаследовано от Object)
GetEditStyle()

Получает стиль редактирования, используемый методом EditValue(IServiceProvider, Object).

GetEditStyle(ITypeDescriptorContext)

Получает стиль редактирования, используемый методом EditValue(IServiceProvider, Object).

GetHashCode()

Служит хэш-функцией по умолчанию.

(Унаследовано от Object)
GetPaintValueSupported()

Указывает, поддерживает ли этот редактор визуальное представление значения объекта.

GetPaintValueSupported(ITypeDescriptorContext)

Указывает, поддерживает ли указанный контекст визуальное представление значения объекта в пределах определенного контекста.

GetType()

Возвращает объект Type для текущего экземпляра.

(Унаследовано от Object)
MemberwiseClone()

Создает неполную копию текущего объекта Object.

(Унаследовано от Object)
PaintValue(Object, Graphics, Rectangle)

Рисует представление значения указанного объекта на заданном холсте.

PaintValue(PaintValueEventArgs)

Рисует представление значения объекта с помощью указанного аргумента PaintValueEventArgs.

ToString()

Возвращает строку, представляющую текущий объект.

(Унаследовано от Object)

Применяется к

Продукт Версии
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
Windows Desktop 3.0, 3.1, 5, 6, 7, 8, 9, 10

См. также раздел