Exemplarische Vorgehensweise: Implementieren eines Farb-Editors

Das Erweiterbarkeitsmodell für den WPF Designer für Visual Studio ermöglicht es Ihnen, benutzerdefinierte Wert-Editoren für Eigenschaften im Eigenschaftenfenster zur Entwurfszeit zu erstellen. Bei diesen Editoren kann es sich entweder um Inline-Editoren handeln, die es Ihnen ermöglichen, Werte direkt im Eigenschaftenfenster zu bearbeiten, oder um erweiterte Editoren, mit denen Sie eine zusätzliche Benutzeroberfläche für das Bearbeiten einer Eigenschaft außerhalb des Eigenschaftenfensters bereitstellen können. In dieser exemplarischen Vorgehensweise wird anhand detaillierter Anweisungen zum Erstellen eines Farb-Editors für die Background-Eigenschaft eines Steuerelements veranschaulicht, wie Sie einen erweiterten Editor erstellen. Dieser erweiterte Editor wird über einen Inline-Editor im Eigenschaftenfenster geöffnet.

Im Verlauf dieser exemplarischen Vorgehensweise führen Sie folgende Aufgaben aus:

  • Erstellen eines Projekts mit einer benutzerdefinierten WPF-Steuerelementbibliothek

  • Erstellen eines Benutzersteuerelements, das als erweiterter Editor fungiert

  • Erstellen eines Inline-Editors, mit dem der Eigenschaftswert im Eigenschaftenfenster bearbeitet werden kann, und Öffnen des erweiterten Editors

  • Erstellen einer Klasse, die von dem ExtendedPropertyValueEditor-Element erbt, welches verwendet wird, um die Editoren mit der Klasse zu verbinden, für die Sie die benutzerdefinierte Bearbeitung bereitstellen möchten

  • Erstellen Sie eine Klasse, die die IProvideAttributeTable-Schnittstelle implementiert, um den neuen erweiterten Editor zu registrieren.

  • Testen des erweiterten Editors zur Entwurfszeit

Vorbereitungsmaßnahmen

Zum Durchführen dieser exemplarischen Vorgehensweise benötigen Sie die folgenden Komponenten:

  • Visual Studio 2010.

Erstellen des benutzerdefinierten Steuerelements

Zuerst wird das Projekt für das benutzerdefinierte Steuerelement erstellt. Bei dem Steuerelement handelt es sich um eine einfache Schaltfläche mit wenig Entwurfszeitcode, für die eine GetIsInDesignMode-Methode zum Implementieren eines Entwurfszeitverhaltens verwendet wird.

So erstellen Sie das benutzerdefinierte Steuerelement

  1. Erstellen Sie ein neues benutzerdefiniertes WPF-Steuerelementbibliothek-Projekt in Visual C# mit dem Namen CustomControlLibrary.

    Der Code für CustomControl1 wird im Code-Editor geöffnet.

  2. Ersetzen Sie im Code-Editor für CustomControl1 den Code im CustomControlLibrary-Namespace durch den folgenden Code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace CustomControlLibrary
    {
        public class CustomControl1 : Button
        {
            public CustomControl1()
            {
                if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
                {
                    Background = Brushes.Red;
                }
            }
        }
    }
    
  3. Legen Sie den Ausgabepfad des Projekts auf "bin\" fest.

  4. Erstellen Sie die Projektmappe.

Erstellen des Benutzersteuerelements für den erweiterten Editor

Das im vorherigen Verfahren erstellte Steuerelement ist das Steuerelement, an das Sie den benutzerdefinierten Farb-Editor anfügen. In diesem Verfahren erstellen Sie ein weiteres Benutzersteuerelement, das als erweiterter Editor fungiert.

So erstellen Sie das Benutzersteuerelement, das als erweiterter Editor fungiert

  1. Fügen Sie in Visual C# der Projektmappe ein neues Projekt mit einer benutzerdefinierten WPF-Steuerelementbibliothek mit dem Namen CustomControlLibrary.Design hinzu.

    Der Code für CustomControl1 wird im Code-Editor geöffnet.

  2. Löschen Sie im Projektmappen-Explorer die Datei CustomControl1 aus dem CustomControlLibrary.Design-Projekt.

  3. Fügen Sie einen Verweis auf die folgenden WPF-Designer-Assemblys hinzu.

    • Microsoft.Windows.Design.Extensibility

    • Microsoft.Windows.Design.Interaction

  4. Fügen Sie einen Verweis auf das CustomControlLibrary-Projekt hinzu.

  5. Legen Sie den Ausgabepfad des Projekts auf folgenden Pfad fest: ".. \CustomControlLibrary\bin\". Dadurch wird die Assembly des Steuerelements im gleichen Ordner wie die Metadatenassembly gespeichert, wodurch Designern die Metadatensuche ermöglicht wird.

  6. Fügen Sie dem CustomControlLibrary.Design-Projekt eine neue Klasse mit dem Namen ColorsList hinzu.

  7. Ersetzen Sie im Code-Editor für ColorsList den automatisch generierten Code durch den folgenden Code.

    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows.Media;
    using System.Reflection;
    using System.Collections.ObjectModel;
    
    namespace CustomControlLibrary.Design
    {
        public class ColorsList : ObservableCollection<Color>
        {
            public ColorsList()
            {
                Type type = typeof(Colors);
                foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Public | BindingFlags.Static))
                {
                    if (propertyInfo.PropertyType == typeof(Color))
                    {
                        Add((Color)propertyInfo.GetValue(null, null));
                    }
                }
            }
        }
    }
    
  8. Fügen Sie dem CustomControlLibrary.Design-Projekt ein neues Benutzersteuerelement (WPF) mit dem Namen ColorsListControl hinzu.

    Der Code für ColorsListControl.xaml wird im Designer geöffnet.

  9. Ersetzen Sie in der XAML-Ansicht für ColorsListControl.xaml den automatisch generierten XAML-Code durch den folgenden XAML-Code.

        <UserControl x:Class="CustomControlLibrary.Design.ColorsListControl"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Local="clr-namespace:CustomControlLibrary.Design" 
        xmlns:PropertyEditing="clr-namespace:Microsoft.Windows.Design.PropertyEditing;assembly=Microsoft.Windows.Design.Interaction"
        Height="184" Width="260" Background="White">
        <UserControl.Resources>
            <Local:ColorsList x:Key="colors"/>
            <Style TargetType="{x:Type Button}">
                <EventSetter Event="Click" Handler="ItemsControl_Click"/>
            </Style>
        </UserControl.Resources>
    
        <ItemsControl 
            ItemsSource="{Binding Source={StaticResource colors}}" 
            HorizontalContentAlignment="Stretch" 
            VerticalContentAlignment="Stretch" 
            HorizontalAlignment="Stretch" 
            VerticalAlignment="Stretch">
            <ItemsControl.Template>
                <ControlTemplate TargetType="ItemsControl">
                    <Border CornerRadius="5" >
                        <WrapPanel Orientation="Horizontal"
                                   VerticalAlignment="Center"
                                   HorizontalAlignment="Center">
                            <ScrollViewer>
                                <ItemsPresenter/>
                            </ScrollViewer>
                        </WrapPanel>
                    </Border>
                </ControlTemplate>
            </ItemsControl.Template>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Button Tag="{Binding}" Command="{x:Static PropertyEditing:PropertyValueEditorCommands.ShowInlineEditor}">
                        <Button.Template>
                            <ControlTemplate>
                                <Border Width="30" Height="30" BorderBrush="Black" BorderThickness="1" CornerRadius="5">
                                    <Rectangle Width="22" Height="22" ToolTip="{Binding}">
                                        <Rectangle.Fill>
                                            <SolidColorBrush Color="{Binding}"/>
                                        </Rectangle.Fill>
                                    </Rectangle>
                                </Border>
                            </ControlTemplate>
                        </Button.Template>
                    </Button>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </UserControl>
    
  10. Erweitern Sie im Projektmappen-Explorer ColorsListControl.xaml, und öffnen Sie ColorsListControl.xaml.cs.

  11. Ersetzen Sie im Code-Editor für ColorsListControl den automatisch generierten Code durch den folgenden Code.

    using System;
    using System.Linq;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace CustomControlLibrary.Design
    {
        public partial class ColorsListControl : System.Windows.Controls.UserControl
        {
            public ColorsListControl()
            {
                InitializeComponent();
            }
    
            public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorsListControl), new FrameworkPropertyMetadata(null));
            public Color SelectedColor
            {
                get { return (Color)base.GetValue(SelectedColorProperty); }
                set { base.SetValue(SelectedColorProperty, value); }
            }
    
            public static readonly DependencyProperty SelectedBrushProperty = DependencyProperty.Register("SelectedBrush", typeof(SolidColorBrush), typeof(ColorsListControl), new FrameworkPropertyMetadata(null));
            public SolidColorBrush SelectedBrush
            {
                get { return (SolidColorBrush)base.GetValue(SelectedBrushProperty); }
                set { base.SetValue(SelectedBrushProperty, value); }
            }
    
            private void ItemsControl_Click(object sender, RoutedEventArgs e)
            {
                SelectedColor = (Color)((Button)sender).Tag;
                SelectedBrush = new SolidColorBrush(SelectedColor);
            }
        }
    }
    
  12. Erstellen Sie die Projektmappe.

  13. Laden Sie ColorsListControl.xaml erneut im Designer. Die Benutzeroberfläche des erweiterten Editors sollte in der Entwurfsansicht angezeigt werden.

Erstellen der Vorlagen für den Farb-Editor

Der Inline-Editor für den Farb-Editor ist nicht so komplex wie der erweiterte Editor und kann mithilfe einer XAML-Datenvorlage erstellt werden. Sie erstellen auch eine Datenvorlage für den erweiterten Editor, die angibt, wie das im vorherigen Verfahren erstellte Benutzersteuerelement verwendet wird.

So erstellen Sie die Vorlage für den Farb-Editor

  1. Fügen Sie dem CustomControlLibrary.Design-Projekt eine neue Klasse mit dem Namen EditorResources hinzu.

  2. Ersetzen Sie im Code-Editor für EditorResources den automatisch generierten Code durch den folgenden Code.

    namespace ExtendedEditorNamespace
    {
        using System;
        using System.Collections.Generic;
        using System.Text;
        using System.Windows;
        public partial class EditorResources : ResourceDictionary {
            public EditorResources()
                : base()
            {
                InitializeComponent();
            }
        }
    }
    
  3. Klicken Sie im Menü Projekt auf Ressourcenwörterbuch hinzufügen.

  4. Nennen Sie die Datei EditorResources.xaml, und klicken Sie auf Hinzufügen.

    Der Code für EditorResources.xaml wird im Designer geöffnet.

  5. Ersetzen Sie in der XAML-Ansicht für EditorResources.xaml den automatisch generierten XAML-Code durch den folgenden XAML-Code.

        <ResourceDictionary
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:PropertyEditing="clr-namespace:Microsoft.Windows.Design.PropertyEditing;assembly=Microsoft.Windows.Design.Interaction"
        xmlns:Local="clr-namespace:CustomControlLibrary.Design"
        xmlns:Media="clr-namespace:System.Windows.Media;assembly=PresentationCore"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        x:Class="CustomControlLibrary.Design.EditorResources">
    
        <DataTemplate x:Key="BrushExtendedEditorTemplate">
            <Local:ColorsListControl SelectedBrush="{Binding Value, Mode=TwoWay}"/>
        </DataTemplate>
    
    
        <DataTemplate x:Key="BrushInlineEditorTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="1*"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <TextBox Grid.Column="0" Text="{Binding StringValue}"/>
                <PropertyEditing:EditModeSwitchButton Grid.Column="1"/>
            </Grid>
        </DataTemplate>
    
    </ResourceDictionary>
    
  6. Erstellen Sie die Projektmappe.

Kapseln der Vorlagen und Registrieren der Editoren

Die Bearbeitung ist abgeschlossen. Nachdem Sie die Vorlagen für den erweiterten Editor und den Inline-Editor des Farb-Editors erstellt haben, können Sie eine Klasse erstellen, die die Vorlagen kapselt und dann mit dem benutzerdefinierten Steuerelement registriert.

So kapseln und registrieren Sie die Editoren

  1. Fügen Sie dem CustomControlLibrary.Design-Projekt eine neue Klasse mit dem Namen BrushExtendedEditor hinzu.

  2. Ersetzen Sie im Code-Editor für BrushExtendedEditor den automatisch generierten Code durch den folgenden Code.

    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.Windows.Design.PropertyEditing;
    using System.Windows;
    
    namespace CustomControlLibrary.Design
    {
        public class BrushExtendedEditor : ExtendedPropertyValueEditor
        {
            private EditorResources res = new EditorResources();
    
            public BrushExtendedEditor()
            {
                this.ExtendedEditorTemplate = res["BrushExtendedEditorTemplate"] as DataTemplate;
                this.InlineEditorTemplate = res["BrushInlineEditorTemplate"] as DataTemplate;
            }
        }
    }
    
  3. Fügen Sie dem CustomControlLibrary.Design-Projekt eine neue Klasse mit dem Namen Metadata hinzu.

  4. Ersetzen Sie im Code-Editor für Metadata den automatisch generierten Code durch den folgenden Code.

    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.Windows.Design.Metadata;
    using System.ComponentModel;
    using Microsoft.Windows.Design.PropertyEditing;
    using System.Windows.Media;
    using System.Windows.Controls;
    using System.Windows;
    using CustomControlLibrary;
    
    // The ProvideMetadata assembly-level attribute indicates to designers
    // that this assembly contains a class that provides an attribute table. 
    [assembly: ProvideMetadata(typeof(CustomControlLibrary.Design.Metadata))]
    
    namespace CustomControlLibrary.Design
    {
        // Container for any general design-time metadata to initialize.
        // Designers look for a type in the design-time assembly that 
        // implements IProvideAttributeTable. If found, designers instantiate 
        // this class and access its AttributeTable property automatically.
        internal class Metadata : IProvideAttributeTable
        {
            // Accessed by the designer to register any design-time metadata.
            public AttributeTable AttributeTable
            {
                get
                {
                    AttributeTableBuilder builder = new AttributeTableBuilder();
    
                    builder.AddCustomAttributes
                        (typeof(CustomControl1),
                        "Background",
                        PropertyValueEditor.CreateEditorAttribute(
                            typeof(BrushExtendedEditor)));
    
                    return builder.CreateTable();
                }
            }
        }
    }
    
  5. Erstellen Sie die Projektmappe.

Testen des Farb-Editors

Sie haben gerade den Farb-Editor erstellt. Jetzt muss er nur noch getestet werden. Um den Editor zu testen, fügen Sie der Projektmappe ein WPF-Anwendungsprojekt und dem Projekt das benutzerdefinierte Steuerelement hinzu. Ändern Sie dann den Hintergrund im Eigenschaftenfenster, und sehen Sie sich den neuen Editor in Aktion an.

So testen Sie den Farb-Editor

  1. Fügen Sie der Projektmappe ein neues WPF-Anwendungsprojekt in Visual C# mit dem Namen DemoApplication hinzu.

    Die Datei MainWindow.xaml wird im WPF-Designer geöffnet.

  2. Fügen Sie einen Verweis auf das CustomControlLibrary-Projekt hinzu.

  3. Ersetzen Sie in der XAML-Ansicht für MainWindow.xaml den automatisch generierten XAML-Code durch folgenden XAML-Code. Mit diesem XAML-Code werden ein Verweis auf den CustomControlLibrary-Namespace sowie das benutzerdefinierte CustomControl1-Steuerelement hinzugefügt. Die Schaltfläche wird in der Entwurfsansicht mit einem roten Hintergrund angezeigt, was darauf hinweist, dass sich das Steuerelement im Entwurfsmodus befindet. Wenn die Schaltfläche nicht angezeigt wird, müssen Sie möglicherweise auf die Informationsleiste am oberen Rand des Designers klicken, um die Ansicht zu aktualisieren.

        <Window x:Class="DemoApplication.MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300" xmlns:my="clr-namespace:CustomControlLibrary;assembly=CustomControlLibrary">
        <Grid>
            <my:CustomControl1 Margin="30,30,30,30" Name="customControl11"></my:CustomControl1>
        </Grid>
    </Window>
    
  4. Wählen Sie das Steuerelement in der Entwurfsansicht aus.

  5. Klicken Sie im Eigenschaftenfenster neben der Background-Eigenschaft auf die Dropdown-Schaltfläche. Statt der Standardliste der Farben wird ein visueller Farb-Editor angezeigt.

  6. Wählen Sie eine Farbe im Editor aus. Die Hintergrundfarbe des benutzerdefinierten Steuerelements ändert sich entsprechend.

Siehe auch

Aufgaben

Exemplarische Vorgehensweise: Implementieren eines Inlinewert-Editors

Gewusst wie: Erstellen eines Wert-Editors

Weitere Ressourcen

Erstellen von benutzerdefinierten Editoren

WPF-Designer-Erweiterbarkeit