Sdílet prostřednictvím


Exemplarische Vorgehensweise: Erstellen eines Kategorie-Editors

Aktualisiert: November 2007

Das Erweiterbarkeitsmodell für den Windows Presentation Foundation (WPF)-Designer für Visual Studio ermöglicht es Ihnen, benutzerdefinierte Editoren für Kategorien von Eigenschaften, so genannte Kategorie-Editoren, zu erstellen. Mit Kategorie-Editoren können Sie eine benutzerdefinierte Benutzerschnittstelle bereitstellen, mit denen Benutzer zugehörige Eigenschaften einer einzelnen Kategorie bearbeiten können, z. B. textbezogene Eigenschaften. In dieser exemplarischen Vorgehensweise erstellen Sie einen Kategorie-Editor, mit dem Benutzer die textbezogenen Eigenschaften eines Steuerelements bearbeiten können.

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

  • Erstellen eines benutzerdefinierten WPF-Steuerelementprojekts

  • Erstellen eines Kategorie-Editors, mit dem die textbezogenen Eigenschaften dieses Steuerelements bearbeitet werden können

  • Erstellen einer Klasse, die von CategoryEditor erbt, der den Kategorie-Editor für das Steuerelement darstellt

  • Erstellen einer Klasse, die von IRegisterMetadata erbt, um den neuen erweiterten Editor zu registrieren

  • Testen des Kategorie-Editors zur Entwurfszeit

Vorbereitungsmaßnahmen

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

  • Visual Studio 2008.

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. Fügen Sie einen Verweis auf die folgende WPF-Designer-Assembly hinzu:

    • Microsoft.Windows.Design
  3. Ersetzen Sie im Code-Editor für CustomControl1 den Code im CustomControlLibrary-Namespace durch den folgenden Code:

    public class CustomControl1 : Button
    {
        public CustomControl1()
        {
            if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
            {
                Content = "I'm in design mode";
            }
        }
    }
    
  4. Legen Sie den Ausgabepfad des Projekts auf "bin\" fest.

  5. Erstellen Sie die Projektmappe.

Erstellen einer Klasse zum Kapseln von Eigenschafteninformationen

Der von Ihnen erstellte Kategorie-Editor benötigt verschiedene Informationen zu Schriftarten und zugeordneten Eigenschaften. Erstellen Sie also eine Klasse, die diese Informationen kapselt. Diese Klasse wird vom Kategorie-Editor als Datenquelle verwendet.

So erstellen Sie eine Klasse, die Informationen zu Schrifteigenschaften kapselt

  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. Löschen Sie im Projektmappen-Explorer den Ordner Designs aus dem CustomControlLibrary.Design-Projekt.

  4. Fügen Sie einen Verweis auf die folgende WPF-Designer-Assembly hinzu:

    • Microsoft.Windows.Design
  5. Fügen Sie einen Verweis auf das CustomControlLibrary-Projekt hinzu.

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

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

  8. Ersetzen Sie im Code-Editor für FontList 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.Collections.ObjectModel;
    using System.Windows;
    using System.Windows.Data;
    using System.Globalization;
    
    namespace CustomControlLibrary.Design
    {
        public class FontList : ObservableCollection<FontFamily>
        {
            public FontList()
            {
                foreach (FontFamily ff in Fonts.SystemFontFamilies)
                {
                    Add(ff);
                }
            }
        }
    
        public class FontSizeList : ObservableCollection<double>
        {
            public FontSizeList()
            {
                Add(8);
                Add(9);
                Add(10);
                Add(11);
                Add(12);
                Add(14);
                Add(16);
                Add(18);
                Add(20);
            }
        }
    
        public class FontStyleConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                FontStyle fs = (FontStyle)value;
                return fs == FontStyles.Italic;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                if (value != null)
                {
                    bool isSet = (bool)value;
    
                    if (isSet)
                    {
                        return FontStyles.Italic;
                    }
                }
    
                return FontStyles.Normal;
            }
        }
    
        public class FontWeightConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                FontWeight fs = (FontWeight)value;
                return fs == FontWeights.Bold;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                if (value != null)
                {
                    bool isSet = (bool)value;
    
                    if (isSet)
                    {
                        return FontWeights.Bold;
                    }
                }
    
                return FontWeights.Normal;
            }
        }
    
    }
    

Erstellen der Vorlage für den Kategorie-Editor

Der Kategorie-Editor wird mithilfe einer XAML-Datenvorlage erstellt. Dies ist eine einfache Benutzeroberfläche, die an mehrere textbezogene Eigenschaften gebunden ist.

So erstellen Sie die Vorlage für den Kategorie-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 CustomControlLibrary.Design
    {
        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.

  5. Ersetzen Sie in der XAML-Ansicht für EditorResources 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"
        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">
        <Local:FontList x:Key="FontFamilyList"/>
        <Local:FontSizeList x:Key="FontSizeList"/>
        <Local:FontStyleConverter x:Key="FontStyleConverter"/>
        <Local:FontWeightConverter x:Key="FontWeightConverter"/>
        <DataTemplate x:Key="TextCategoryEditorTemplate">
            <StackPanel Margin="5">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="1*"/>
                        <ColumnDefinition Width="50"/>
                    </Grid.ColumnDefinitions>
                    <ComboBox 
                        Grid.Column="0"
                        Margin="2"
                        ItemsSource="{Binding Source={StaticResource FontFamilyList}}" 
                        DisplayMemberPath="FamilyNames.Values[0]"
                        SelectedItem="{Binding [FontFamily].PropertyValue.Value}"/>
                    <ComboBox 
                        Grid.Column="1"
                        Margin="2"
                        ItemsSource="{Binding Source={StaticResource FontSizeList}}"
                        SelectedItem="{Binding [FontSize].PropertyValue.Value}"/>
                </Grid>
                <StackPanel Orientation="Horizontal">
                    <CheckBox 
                        Margin="2"
                        Content="Bold"
                        IsChecked="{Binding Path=[FontWeight].PropertyValue.Value, Converter={StaticResource FontWeightConverter}}"/>
                    <CheckBox 
                        Margin="2"
                        Content="Italic"
                        IsChecked="{Binding Path=[FontStyle].PropertyValue.Value, Converter={StaticResource FontStyleConverter}}"/>
                </StackPanel>
            </StackPanel>
        </DataTemplate>
    </ResourceDictionary>
    
  6. Erstellen Sie die Projektmappe.

Kapseln der Vorlage und Registrieren des Kategorie-Editors

Nachdem Sie die Vorlage für den Kategorie-Editor erstellt haben, müssen Sie eine Klasse erstellen, die von CategoryEditor erbt, um die Vorlage als benutzerdefinierten Editor zu verwenden, und Sie müssen den neuen Kategorie-Editor registrieren.

So kapseln und registrieren Sie den Kategorie-Editor

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

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

    namespace CustomControlLibrary.Design {
        using System;
        using System.Collections.Generic;
        using System.Text;
        using System.Windows;
        using System.Windows.Controls;
        using System.Windows.Data;
        using Microsoft.Windows.Design.PropertyEditing;
    
        public class TextCategoryEditor : CategoryEditor {
    
            private EditorResources res = new EditorResources();
            public TextCategoryEditor()
            {
            }
    
            public override bool ConsumesProperty(PropertyEntry property)
            {
                return true;
            }
    
            public override DataTemplate EditorTemplate
            {
                get {
                    return res["TextCategoryEditorTemplate"] as DataTemplate;
                }
            }
    
            public override object GetImage(Size desiredSize)
            {
                return null;
            }
    
            public override string TargetCategory
            {
                get { return "Text"; }
            }
        }
    }
    
  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.

    namespace CustomControlLibrary.Design
    {
        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;
    
        // Container for any general design-time metadata that we want to initialize.
        // Designers will look for a type in the design-time assembly that implements IRegisterMetadata.
        // If found, they will instantiate it and call its Register() method automatically.
        internal class Metadata : IRegisterMetadata
        {
    
            // Called by the WPF Designer to register any design-time metadata
            public void Register()
            {
                AttributeTableBuilder builder = new AttributeTableBuilder();
                builder.AddCustomAttributes
                    (typeof( CustomControl1), 
                    "Enter text",
                    PropertyValueEditor.CreateEditorAttribute(
                        typeof(TextCategoryEditor)));
                MetadataStore.AddAttributeTable(builder.CreateTable());
            }
        }
    }
    
  5. Erstellen Sie die Projektmappe.

Testen des Kategorie-Editors

Der Kategorie-Editor ist nun vollständig und kann verwendet werden. Nun muss er getestet werden. Um den Kategorie-Editor zu testen, fügen Sie eine WPF-Anwendung zu Ihrem Projekt hinzu, fügen das benutzerdefinierte Steuerelement zur WPF-Anwendung hinzu und überprüfen den Kategorie-Editor in Aktion.

So testen Sie den Kategorie-Editor

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

    In WPF-Designer wird die Datei Window1.xaml geöffnet.

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

  3. Ersetzen Sie in der XAML-Ansicht für Window1.xaml den automatisch generierten XAML-Code durch den folgenden XAML-Code. Mit diesem XAML-Code wird ein Verweis auf den CustomControlLibrary-Namespace sowie das benutzerdefinierte CustomControl1-Steuerelement hinzugefügt. Die Schaltfläche wird in der Ansicht Entwurf mit einem Text angezeigt, der darauf hinweist, dass sie sich 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.Window1"
        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 Ansicht Entwurf aus.

  5. Suchen Sie im Fenster Eigenschaften die Textkategorie.

    Es sollte eine Benutzeroberfläche zum Angeben von Texteigenschaften angezeigt werden, die sich von anderen Steuerelementen unterscheidet. Sie können in Dropdownlisten einen Schriftartnamen und einen Schriftgrad auswählen. Durch Aktivieren der entsprechenden Kontrollkästchen können Sie fett oder kursiv formatierten Text festlegen.

  6. Nehmen Sie Änderungen an den in dieser Kategorie dargestellten Eigenschaften vor. Beachten Sie, dass sich diese Änderungen auf das Steuerelement auswirken.

Siehe auch

Aufgaben

Exemplarische Vorgehensweise: Implementieren eines Farb-Editors

Gewusst wie: Erstellen eines Wert-Editors

Weitere Ressourcen

Erstellen von benutzerdefinierten Editoren

WPF-Designer-Erweiterbarkeit