Udostępnij za pośrednictwem


Wskazówki: implementowanie edytora typów interfejsu

Niestandardowe doświadczenie w czasie projektowania typy właściwości złożonej można zapewnić przez zaimplementowanie edytora typu interfejsu użytkownika.

W tym instruktażu opisano sposób autor własnego edytora typu interfejsu użytkownika dla niestandardowego typu i wyświetlić interfejs edycji za pomocą PropertyGrid.

Wyjaśniono, w tym instruktażu zadania obejmują:

  • Definiowanie niestandardowego typu.

  • Definiowanie formantu widoku edytora typu interfejsu użytkownika.

  • Definiowanie klasy, który wynika z UITypeEditor.

  • Przesłanianie GetEditStyle metody informowania PropertyGrid typu stylu edytor, który będzie używany w edytorze.

  • Przesłanianie EditValue metody obsługi interfejsu użytkownika, przetwarzanie wejściowych użytkownika i przypisanie wartości.

Aby skopiować kod w tym instruktażu jako pojedynczy aukcji, zobacz Porady: tworzenie formantu formularzy Windows wykorzystującego funkcje czasu projektowania.

Wymagania wstępne

W celu przeprowadzenia tego instruktażu będą potrzebne:

  • Wystarczające uprawnienia, aby móc utworzyć i uruchomić Windows Forms projektów aplikacji na komputerze, gdzie .NET Framework jest zainstalowany.

Definiowanie niestandardowy typ

Edytor typu niestandardowego UI zostaną wyświetlone typ niestandardowy.Tego typu może być złożone lub proste.Dla tego instruktażu określi typu prostego z niestandardowego zachowania podczas edycji czasu projektowania.Ten typ jest nazywany MarqueeLightShape, i jest enum z dwóch wartości, Square i Circle.

Aby zdefiniować typ wyliczenia niestandardowe

  • W treści definicji formantu Windows Forms zdefiniować MarqueeLightShape typu.

    ' This defines the possible values for the MarqueeBorder 
    ' control's LightShape property. 
    Public Enum MarqueeLightShape
        Square
        Circle
    End Enum
    
    // This defines the possible values for the MarqueeBorder 
    // control's LightShape property. 
    public enum MarqueeLightShape
    {
        Square,
        Circle
    }
    

Definiowanie formantu widoku

Edytor typu niestandardowego UI wyświetla interfejs edycji, przy użyciu formantu Windows Forms.Ten formant o nazwie LightShapeSelectionControl, i pochodzi ona od UserControl.Jego konstruktora pobiera bieżącą wartość właściwości i odniesienie do IWindowsFormsEditorService.Wykorzystuje formant w widoku CloseDropDown metody na IWindowsFormsEditorService aby zamknąć okno drop-down, gdy użytkownik kliknie na zaznaczenie.

Aby zdefiniować formantu widoku

  • W treści definicji formantu Windows Forms zdefiniować LightShapeSelectionControl kontroli.

    ' This control provides the custom UI for the LightShape property 
    ' of the MarqueeBorder. It is used by the LightShapeEditor. 
    Public Class LightShapeSelectionControl
        Inherits System.Windows.Forms.UserControl
    
       Private lightShapeValue As MarqueeLightShape = MarqueeLightShape.Square
    
        Private editorService As IWindowsFormsEditorService
       Private squarePanel As System.Windows.Forms.Panel
       Private circlePanel As System.Windows.Forms.Panel
    
       ' Required designer variable. 
       Private components As System.ComponentModel.Container = Nothing 
    
    
       ' This constructor takes a MarqueeLightShape value from the 
       ' design-time environment, which will be used to display 
       ' the initial state. 
        Public Sub New( _
        ByVal lightShape As MarqueeLightShape, _
        ByVal editorService As IWindowsFormsEditorService)
            ' This call is required by the Windows.Forms Form Designer.
            InitializeComponent()
    
            ' Cache the light shape value provided by the  
            ' design-time environment. 
            Me.lightShapeValue = lightShape
    
            ' Cache the reference to the editor service. 
            Me.editorService = editorService
    
            ' Handle the Click event for the two panels.  
            AddHandler Me.squarePanel.Click, AddressOf squarePanel_Click
            AddHandler Me.circlePanel.Click, AddressOf circlePanel_Click
        End Sub 
    
        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            If disposing Then 
    
                ' Be sure to unhook event handlers 
                ' to prevent "lapsed listener" leaks. 
                RemoveHandler Me.squarePanel.Click, AddressOf squarePanel_Click
                RemoveHandler Me.circlePanel.Click, AddressOf circlePanel_Click
    
                If (components IsNot Nothing) Then
                    components.Dispose()
                End If 
    
            End If 
            MyBase.Dispose(disposing)
        End Sub 
    
        ' LightShape is the property for which this control provides 
        ' a custom user interface in the Properties window. 
        Public Property LightShape() As MarqueeLightShape
    
            Get 
                Return Me.lightShapeValue
            End Get 
    
            Set(ByVal Value As MarqueeLightShape)
                If Me.lightShapeValue <> Value Then 
                    Me.lightShapeValue = Value
                End If 
            End Set 
    
        End Property 
    
        Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
            MyBase.OnPaint(e)
    
            Dim gCircle As Graphics = Me.circlePanel.CreateGraphics()
            Try 
                Dim gSquare As Graphics = Me.squarePanel.CreateGraphics()
                Try 
                    ' Draw a filled square in the client area of 
                    ' the squarePanel control.
                    gSquare.FillRectangle( _
                    Brushes.Red, _
                    0, _
                    0, _
                    Me.squarePanel.Width, _
                    Me.squarePanel.Height)
    
                    ' If the Square option has been selected, draw a  
                    ' border inside the squarePanel. 
                    If Me.lightShapeValue = MarqueeLightShape.Square Then
                        gSquare.DrawRectangle( _
                        Pens.Black, _
                        0, _
                        0, _
                        Me.squarePanel.Width - 1, _
                        Me.squarePanel.Height - 1)
                    End If 
    
                    ' Draw a filled circle in the client area of 
                    ' the circlePanel control.
                    gCircle.Clear(Me.circlePanel.BackColor)
                    gCircle.FillEllipse( _
                    Brushes.Blue, _
                    0, _
                    0, _
                    Me.circlePanel.Width, _
                    Me.circlePanel.Height)
    
                    ' If the Circle option has been selected, draw a  
                    ' border inside the circlePanel. 
                    If Me.lightShapeValue = MarqueeLightShape.Circle Then
                        gCircle.DrawRectangle( _
                        Pens.Black, _
                        0, _
                        0, _
                        Me.circlePanel.Width - 1, _
                        Me.circlePanel.Height - 1)
                    End If 
                Finally
                    gSquare.Dispose()
                End Try 
            Finally
                gCircle.Dispose()
            End Try 
        End Sub 
    
        Private Sub squarePanel_Click( _
        ByVal sender As Object, _
        ByVal e As EventArgs)
    
            Me.lightShapeValue = MarqueeLightShape.Square
            Me.Invalidate(False)
            Me.editorService.CloseDropDown()
    
        End Sub 
    
    
        Private Sub circlePanel_Click( _
        ByVal sender As Object, _
        ByVal e As EventArgs)
    
            Me.lightShapeValue = MarqueeLightShape.Circle
            Me.Invalidate(False)
            Me.editorService.CloseDropDown()
    
        End Sub
    
    #Region "Component Designer generated code" 
    
        '/ <summary>  
        '/ Required method for Designer support - do not modify  
        '/ the contents of this method with the code editor. 
        '/ </summary> 
        Private Sub InitializeComponent()
            Me.squarePanel = New System.Windows.Forms.Panel
            Me.circlePanel = New System.Windows.Forms.Panel
            Me.SuspendLayout()
            '  
            ' squarePanel 
            '  
            Me.squarePanel.Location = New System.Drawing.Point(8, 10)
            Me.squarePanel.Name = "squarePanel" 
            Me.squarePanel.Size = New System.Drawing.Size(60, 60)
            Me.squarePanel.TabIndex = 2
            '  
            ' circlePanel 
            '  
            Me.circlePanel.Location = New System.Drawing.Point(80, 10)
            Me.circlePanel.Name = "circlePanel" 
            Me.circlePanel.Size = New System.Drawing.Size(60, 60)
            Me.circlePanel.TabIndex = 3
            '  
            ' LightShapeSelectionControl 
            '  
            Me.Controls.Add(squarePanel)
            Me.Controls.Add(circlePanel)
            Me.Name = "LightShapeSelectionControl" 
            Me.Size = New System.Drawing.Size(150, 80)
            Me.ResumeLayout(False)
        End Sub
    
    #End Region
    
    End Class
    
    // This control provides the custom UI for the LightShape property 
        // of the MarqueeBorder. It is used by the LightShapeEditor. 
        public class LightShapeSelectionControl : System.Windows.Forms.UserControl
        {
            private MarqueeLightShape lightShapeValue = MarqueeLightShape.Square;
            private IWindowsFormsEditorService editorService = null;
            private System.Windows.Forms.Panel squarePanel;
            private System.Windows.Forms.Panel circlePanel;
    
            // Required designer variable. 
            private System.ComponentModel.Container components = null;
    
            // This constructor takes a MarqueeLightShape value from the 
            // design-time environment, which will be used to display 
            // the initial state. 
            public LightShapeSelectionControl( 
                MarqueeLightShape lightShape,
                IWindowsFormsEditorService editorService )
            {
                // This call is required by the designer.
                InitializeComponent();
    
                // Cache the light shape value provided by the  
                // design-time environment. 
                this.lightShapeValue = lightShape;
    
                // Cache the reference to the editor service. 
                this.editorService = editorService;
    
                // Handle the Click event for the two panels.  
                this.squarePanel.Click += new EventHandler(squarePanel_Click);
                this.circlePanel.Click += new EventHandler(circlePanel_Click);
            }
    
            protected override void Dispose( bool disposing )
            {
                if( disposing )
                {
                    // Be sure to unhook event handlers 
                    // to prevent "lapsed listener" leaks.
                    this.squarePanel.Click -= 
                        new EventHandler(squarePanel_Click);
                    this.circlePanel.Click -= 
                        new EventHandler(circlePanel_Click);
    
                    if(components != null)
                    {
                        components.Dispose();
                    }
                }
                base.Dispose( disposing );
            }
    
            // LightShape is the property for which this control provides 
            // a custom user interface in the Properties window. 
            public MarqueeLightShape LightShape
            {
                get
                {
                    return this.lightShapeValue;
                }
    
                set
                {
                    if( this.lightShapeValue != value )
                    {
                        this.lightShapeValue = value;
                    }
                }
            }
    
            protected override void OnPaint(PaintEventArgs e)
            {
                base.OnPaint (e);
    
                using( 
                    Graphics gSquare = this.squarePanel.CreateGraphics(),
                    gCircle = this.circlePanel.CreateGraphics() )
                {   
                    // Draw a filled square in the client area of 
                    // the squarePanel control.
                    gSquare.FillRectangle(
                        Brushes.Red, 
                        0,
                        0,
                        this.squarePanel.Width,
                        this.squarePanel.Height
                        );
    
                    // If the Square option has been selected, draw a  
                    // border inside the squarePanel. 
                    if( this.lightShapeValue == MarqueeLightShape.Square )
                    {
                        gSquare.DrawRectangle( 
                            Pens.Black,
                            0,
                            0,
                            this.squarePanel.Width-1,
                            this.squarePanel.Height-1);
                    }
    
                    // Draw a filled circle in the client area of 
                    // the circlePanel control.
                    gCircle.Clear( this.circlePanel.BackColor );
                    gCircle.FillEllipse( 
                        Brushes.Blue, 
                        0,
                        0,
                        this.circlePanel.Width, 
                        this.circlePanel.Height
                        );
    
                    // If the Circle option has been selected, draw a  
                    // border inside the circlePanel. 
                    if( this.lightShapeValue == MarqueeLightShape.Circle )
                    {
                        gCircle.DrawRectangle( 
                            Pens.Black,
                            0,
                            0,
                            this.circlePanel.Width-1,
                            this.circlePanel.Height-1);
                    }
                }   
            }
    
            private void squarePanel_Click(object sender, EventArgs e)
            {
                this.lightShapeValue = MarqueeLightShape.Square;
    
                this.Invalidate( false );
    
                this.editorService.CloseDropDown();
            }
    
            private void circlePanel_Click(object sender, EventArgs e)
            {
                this.lightShapeValue = MarqueeLightShape.Circle;
    
                this.Invalidate( false );
    
                this.editorService.CloseDropDown();
            }
    
            #region Component Designer generated code
            /// <summary>  
            /// Required method for Designer support - do not modify  
            /// the contents of this method with the code editor. 
            /// </summary> 
            private void InitializeComponent()
            {
                this.squarePanel = new System.Windows.Forms.Panel();
                this.circlePanel = new System.Windows.Forms.Panel();
                this.SuspendLayout();
    //  
    // squarePanel 
    //  
                this.squarePanel.Location = new System.Drawing.Point(8, 10);
                this.squarePanel.Name = "squarePanel";
                this.squarePanel.Size = new System.Drawing.Size(60, 60);
                this.squarePanel.TabIndex = 2;
    //  
    // circlePanel 
    //  
                this.circlePanel.Location = new System.Drawing.Point(80, 10);
                this.circlePanel.Name = "circlePanel";
                this.circlePanel.Size = new System.Drawing.Size(60, 60);
                this.circlePanel.TabIndex = 3;
    //  
    // LightShapeSelectionControl 
    //  
                this.Controls.Add(this.squarePanel);
                this.Controls.Add(this.circlePanel);
                this.Name = "LightShapeSelectionControl";
                this.Size = new System.Drawing.Size(150, 80);
                this.ResumeLayout(false);
    
            }
            #endregion
    
    
        }
    

Określenie typu interfejsu użytkownika edytora klasy

Aby zaimplementować zachowanie edytora typu interfejsu użytkownika, pochodzić od UITypeEditor klasa podstawowa.Ta klasa jest nazywany LightShapeEditor.

Aby zdefiniować typ interfejsu użytkownika edytora, klasa

  1. Włącz dostęp do .NET Framework wsparcia w fazie projektowania poprzez odwołanie do zestawu opcję System.Design i importowanie System.Drawing.Design i System.Windows.Forms.Design obszarów nazw.Aby uzyskać więcej informacji, zobacz Porady: uzyskiwanie dostępu do pomocy technicznej czasu projektowania w formularzach systemu Windows.

  2. W treści definicji formantu okna formularzy, należy zdefiniować LightShapeEditor klasy.

    ' This class demonstrates the use of a custom UITypeEditor.  
    ' It allows the MarqueeBorder control's LightShape property 
    ' to be changed at design time using a customized UI element 
    ' that is invoked by the Properties window. The UI is provided 
    ' by the LightShapeSelectionControl class. 
    Friend Class LightShapeEditor
        Inherits UITypeEditor
    
    // This class demonstrates the use of a custom UITypeEditor.  
    // It allows the MarqueeBorder control's LightShape property 
    // to be changed at design time using a customized UI element 
    // that is invoked by the Properties window. The UI is provided 
    // by the LightShapeSelectionControl class. 
    internal class LightShapeEditor : UITypeEditor
    {
    

Przesłanianie metody GetEditStyle

GetEditStyle Metoda wskazuje na środowisko projektowania, jakiego rodzaju użytkownika interfejs użytkownika implementuje edytora typu interfejsu użytkownika.Możliwe wartości są definiowane w UITypeEditorEditStyle typu.LightShapeEditor Implementuje DropDown edytora typu interfejsu użytkownika.

Aby zastąpić metodę GetEditStyle

  • W treści LightShapeEditor definicji, zastąpić GetEditStyle metoda zwraca DropDown.

    Public Overrides Function GetEditStyle( _
            ByVal context As System.ComponentModel.ITypeDescriptorContext) _
            As UITypeEditorEditStyle
                Return UITypeEditorEditStyle.DropDown
            End Function
    
    public override UITypeEditorEditStyle GetEditStyle(
    System.ComponentModel.ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.DropDown;
    }
    

Przesłanianie metody EditValue

EditValue Metoda ustanawia interakcji między środowisko projektowania i interfejs użytkownika do edytowania niestandardowego typu.EditValue Metoda tworzy wystąpienie formantu widoku lub okno dialogowe modalny, z którym użytkownik edytuje wartość.Po zakończeniu edycji, EditValue metoda zwraca wartość środowisko projektowania.

W odniesieniu do kontroli widoku, podobnie jak LightShapeSelectionControl, EditValue metoda może przekazać odwołanie do IWindowsFormsEditorService do formantu widoku.Formant w widoku można użyć tego odwołania do samego zamykać, gdy użytkownik wybierze wartość.Nie jest to konieczne dla modalnego okna dialogowego, ponieważ sam zamknąć formularz.

Aby zastąpić metodę EditValue

  • W treści LightShapeEditor definicji, zastąpić EditValue metody.

    Public Overrides Function EditValue( _
    ByVal context As ITypeDescriptorContext, _
    ByVal provider As IServiceProvider, _
    ByVal value As Object) As Object 
        If (provider IsNot Nothing) Then
            editorService = _
            CType(provider.GetService(GetType(IWindowsFormsEditorService)), _
            IWindowsFormsEditorService)
        End If 
    
        If (editorService IsNot Nothing) Then 
            Dim selectionControl As _
            New LightShapeSelectionControl( _
            CType(value, MarqueeLightShape), _
            editorService)
    
            editorService.DropDownControl(selectionControl)
    
            value = selectionControl.LightShape
        End If 
    
        Return value
    End Function
    
    public override object EditValue(
        ITypeDescriptorContext context,
        IServiceProvider provider,
        object value)
    {
        if (provider != null)
        {
            editorService =
                provider.GetService(
                typeof(IWindowsFormsEditorService))
                as IWindowsFormsEditorService;
        }
    
        if (editorService != null)
        {
            LightShapeSelectionControl selectionControl =
                new LightShapeSelectionControl(
                (MarqueeLightShape)value,
                editorService);
    
            editorService.DropDownControl(selectionControl);
    
            value = selectionControl.LightShape;
        }
    
        return value;
    }
    

Przesłanianie metody PaintValue

Graficzna reprezentacja wartości swoje właściwości można zapewnić przez zastąpienie PaintValue metody.

Aby zastąpić metodę PaintValue

  • W treści LightShapeEditor definicji, zastąpić PaintValue metody.Również zastąpić GetPaintValueSupported metoda zwraca true.

    ' This method indicates to the design environment that 
    ' the type editor will paint additional content in the 
    ' LightShape entry in the PropertyGrid. 
    Public Overrides Function GetPaintValueSupported( _
    ByVal context As ITypeDescriptorContext) As Boolean 
    
        Return True 
    
    End Function 
    
    ' This method paints a graphical representation of the  
    ' selected value of the LightShpae property. 
    Public Overrides Sub PaintValue( _
    ByVal e As PaintValueEventArgs)
    
        Dim shape As MarqueeLightShape = _
        CType(e.Value, MarqueeLightShape)
        Using p As Pen = Pens.Black
    
            If shape = MarqueeLightShape.Square Then
    
                e.Graphics.DrawRectangle(p, e.Bounds)
    
            Else
    
                e.Graphics.DrawEllipse(p, e.Bounds)
    
            End If 
    
        End Using 
    
    End Sub
    
    // This method indicates to the design environment that 
    // the type editor will paint additional content in the 
    // LightShape entry in the PropertyGrid. 
    public override bool GetPaintValueSupported(
        ITypeDescriptorContext context)
    {  
        return true;
    }
    
    // This method paints a graphical representation of the  
    // selected value of the LightShpae property. 
    public override void PaintValue(PaintValueEventArgs e)
    {   
        MarqueeLightShape shape = (MarqueeLightShape)e.Value;
        using (Pen p = Pens.Black)
        {
            if (shape == MarqueeLightShape.Square)
            {
                e.Graphics.DrawRectangle(p, e.Bounds);
            }
            else
            {
                e.Graphics.DrawEllipse(p, e.Bounds);
            }
        }   
    }
    

Dołączanie edytora typu interfejsu użytkownika do właściwości

Gdy edytor typu interfejsu użytkownika jest gotowa do użytku w sieci formant niestandardowy, należy dołączyć LightShapeEditor do właściwości, należy zaimplementować właściwości, na podstawie MarqueeLightShape typu i stosować EditorAttribute do właściwości.

Aby dołączyć edytora typu interfejsu użytkownika do właściwości

  • W treści programu kontroli definicji zadeklarować MarqueeLightShape właściwość o nazwie LightShape.Również zadeklarować pola wystąpienia o nazwie lightShapeValue typu MarqueeLightShape do właściwości z powrotem.Stosuje się EditorAttribute do właściwości.
Private lightShapeValue As MarqueeLightShape

<Category("Marquee"), _
Browsable(True), _
EditorAttribute(GetType(LightShapeEditor), _
GetType(System.Drawing.Design.UITypeEditor))> _
Public Property LightShape() As MarqueeLightShape
    Get
        Return Me.lightShapeValue
    End Get
    Set(ByVal value As MarqueeLightShape)
        Me.lightShapeValue = value
    End Set
End Property
private MarqueeLightShape lightShapeValue;

[Category("Marquee")]
[Browsable(true)]
[EditorAttribute(typeof(LightShapeEditor),
typeof(System.Drawing.Design.UITypeEditor))]
public MarqueeLightShape LightShape
{
    get
    {
        return this.lightShapeValue;
    }

    set
    {
        this.lightShapeValue = value;
    }
}

Testowanie edytora typu interfejsu użytkownika

Edytor typu interfejsu użytkownika można przetestować przez utworzenie wystąpienia formantu niestandardowego i dołączania ich do PropertyGrid sterować za pomocą SelectedObject właściwości.

Korzystania z programu Visual Studio, można utworzyć nowy projekt aplikacji systemu Windows, odwołać zestawu programu kontroli i dodać instancję formantu do formularza.Istnieje szeroka Obsługa tego zadania w Visual Studio.

Gdy w czasie projektowania, wyświetlane są właściwości dla formantu, można wybrać LightShape właściwości.Gdy jest zaznaczone, strzałka rozwijana (Okno właściwości strzałka w dół) jest wyświetlany.Po kliknięciu strzałki pod zapis właściwości pojawi się formant w widoku.Kliknij okrąg lub kwadrat, aby wybrać wartość.Po kliknięciu formantu widoku zostaje odrzucona, sama i wybraną wartość pojawia się w PropertyGrid.

[!UWAGA]

Podczas rozwijania niestandardowe UITypeEditor, zaleca się, że aby ustawić numer kompilacji do zwiększania z każdej kompilacji.Zapobiega to wersjach starszych, buforowane na UITypeEditor z tworzonych w środowisku projektowym.

Następne kroki

Po zostały utworzone własnego edytora typu interfejsu użytkownika, Poznaj inne sposoby interakcji z PropertyGrid i środowisko projektowania:

Zobacz też

Zadania

Porady: tworzenie formantu formularzy Windows wykorzystującego funkcje czasu projektowania

Informacje

UITypeEditor

EditorAttribute

PropertyGrid

Inne zasoby

Edytory typów interfejsu użytkownika