Partager via


Procédure pas à pas : implémentation d'un éditeur de couleurs

Le modèle d'extensibilité du Concepteur WPF pour Visual Studio permet de créer des éditeurs de valeurs personnalisés pour les propriétés dans la fenêtre Propriétés au moment du design. Les éditeurs peuvent être des éditeurs inline, qui vous permettent de modifier des valeurs directement dans la fenêtre Propriétés, ou des éditeurs étendus, qui vous permettent de fournir une interface utilisateur supplémentaire pour modifier une propriété en dehors de la fenêtre Propriétés. Pour montrer comment créer un éditeur étendu, cette procédure pas à pas fournit les procédures détaillées à suivre pour créer un éditeur de couleurs pour la propriété Background d'un contrôle. Cet éditeur étendu est ouvert à partir d'un éditeur inline de la fenêtre Propriétés.

Dans cette procédure pas à pas, vous allez effectuer les tâches suivantes :

  • créer un projet de contrôle personnalisé WPF ;

  • créer un contrôle utilisateur faisant office d'éditeur étendu ;

  • créer un éditeur inline qui peut être utilisé pour modifier la valeur de propriété dans la fenêtre Propriétés et pour ouvrir l'éditeur étendu ;

  • créer une classe qui hérite de ExtendedPropertyValueEditor servant à connecter les éditeurs à la classe pour laquelle vous souhaitez fournir la modification personnalisée ;

  • Créez une classe qui implémente l'interface IProvideAttributeTable pour inscrire votre nouvel éditeur étendu.

  • tester l'éditeur étendu au moment du design.

Composants requis

Pour exécuter cette procédure pas à pas, vous devez disposer des composants suivants :

  • Visual Studio 2010.

Création du contrôle personnalisé

La première étape consiste à créer le projet pour le contrôle personnalisé. Le contrôle est un bouton simple avec une petite portion de code au moment du design, qui utilise la méthode GetIsInDesignMode pour implémenter un comportement au moment du design.

Pour créer le contrôle personnalisé

  1. Créez un projet de bibliothèque de contrôles personnalisés WPF dans Visual C# nommé CustomControlLibrary.

    Le code pour CustomControl1 s'ouvre dans l'éditeur de code.

  2. Dans l'éditeur de code de CustomControl1, remplacez le code dans l'espace de noms CustomControlLibrary par le code suivant :

    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. Le chemin de sortie du projet doit être "bin\".

  4. Générez la solution.

Création du contrôle utilisateur pour l'éditeur étendu

Le contrôle que vous avez créé dans la procédure précédente est celui que vous allez attacher à votre éditeur de couleurs personnalisé. Dans cette procédure, vous créez un autre contrôle utilisateur qui fait office d'éditeur étendu.

Pour créer le contrôle utilisateur faisant office d'éditeur étendu

  1. Ajoutez à la solution un nouveau projet de bibliothèque de contrôles personnalisés WPF dans Visual C# nommé CustomControlLibrary.Design.

    Le code de CustomControl1 s'ouvre dans l'éditeur de code.

  2. Dans l'Explorateur de solutions, supprimez le fichier CustomControl1 du projet CustomControlLibrary.Design.

  3. Ajoutez une référence aux assemblys Concepteur WPF suivants.

    • Microsoft.Windows.Design.Extensibility

    • Microsoft.Windows.Design.Interaction

  4. Ajoutez une référence au projet CustomControlLibrary.

  5. Affectez au chemin de sortie du projet la valeur \CustomControlLibrary\bin\". Cela permet de garder l'assembly du contrôle et l'assembly de métadonnées dans le même dossier, ce qui active la découverte de métadonnées pour les concepteurs.

  6. Ajoutez une nouvelle classe nommée ColorsList au projet CustomControlLibrary.Design.

  7. Dans l'éditeur de code pour ColorsList, remplacez le code généré automatiquement par le code suivant.

    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. Ajoutez un nouveau contrôle utilisateur (WPF) nommé ColorsListControl au projet CustomControlLibrary.Design.

    Le code de ColorsListControl.xaml s'ouvre dans le concepteur.

  9. Dans l'affichage de ColorsListControl.xaml en mode XAML, remplacez le code XAML généré automatiquement par le code XAML suivant.

        <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. Dans l'Explorateur de solutions, développez ColorsListControl.xaml et ouvrez ColorsListControl.xaml.cs.

  11. Dans l'éditeur de code pour ColorsListControl, remplacez le code généré automatiquement par le code suivant.

    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. Générez la solution.

  13. Rechargez ColorsListControl.xaml dans le concepteur. L'interface utilisateur de l'éditeur étendu doit normalement apparaître en mode Design.

Création des modèles pour l'éditeur de couleurs

L'éditeur inline associé à votre éditeur de couleurs est moins complexe que l'éditeur étendu et peut être créé avec un modèle de données XAML. Vous créez également un modèle de données pour l'éditeur étendu qui détermine l'utilisation du contrôle utilisateur créé dans la procédure précédente.

Pour créer le modèle pour l'éditeur de couleurs

  1. Ajoutez une nouvelle classe nommée EditorResources au projet CustomControlLibrary.Design.

  2. Dans l'éditeur de code pour EditorResources, remplacez le code généré automatiquement par le code suivant.

    namespace ExtendedEditorNamespace
    {
        using System;
        using System.Collections.Generic;
        using System.Text;
        using System.Windows;
        public partial class EditorResources : ResourceDictionary {
            public EditorResources()
                : base()
            {
                InitializeComponent();
            }
        }
    }
    
  3. Dans le menu Projet, cliquez sur Ajouter un dictionnaire de ressources.

  4. Nommez le fichier EditorResources.xaml, puis cliquez sur Ajouter.

    Le code de EditorResources.xaml s'ouvre dans le concepteur.

  5. Dans l'affichage de EditorResources.xaml en mode XAML, remplacez le code XAML généré automatiquement par le code XAML suivant.

        <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. Générez la solution.

Encapsulation des modèles et inscription des éditeurs

Vous avez déjà effectué le plus dur. Après avoir créé les modèles d'éditeur étendu et inline pour votre éditeur de couleurs, vous pouvez créer une classe qui les encapsule puis les inscrit avec votre contrôle personnalisé.

Pour encapsuler et inscrire les éditeurs

  1. Ajoutez une nouvelle classe nommée BrushExtendedEditor au projet CustomControlLibrary.Design.

  2. Dans l'éditeur de code pour BrushExtendedEditor, remplacez le code généré automatiquement par le code suivant.

    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. Ajoutez une nouvelle classe nommée Metadata au projet CustomControlLibrary.Design.

  4. Dans l'éditeur de code pour Metadata, remplacez le code généré automatiquement par le code suivant.

    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. Générez la solution.

Test de l'éditeur de couleurs

Vous venez de terminé la création de votre éditeur de couleurs. Il ne reste plus qu'à le tester. Pour ce faire, vous allez ajouter un projet d'application WPF à votre solution et ajouter votre contrôle personnalisé. Vous allez ensuite modifier l'arrière-plan dans la fenêtre Propriétés pour afficher votre nouvel éditeur en action.

Pour tester l'éditeur de couleurs

  1. Ajoutez à la solution un nouveau projet d'application WPF dans Visual C# nommé DemoApplication.

    MainWindow.xaml s'ouvre dans le Concepteur WPF.

  2. Ajoutez une référence au projet CustomControlLibrary.

  3. Dans la vue XAML pour MainWindow.xaml, remplacez le code XAML généré automatiquement par le code XAML suivant. Ce code XAML ajoute une référence à l'espace de noms CustomControlLibrary ainsi que le contrôle personnalisé CustomControl1. Le bouton apparaît en mode Design avec un arrière-plan rouge, indiquant que le contrôle est en mode Design. Si le bouton ne s'affiche pas, il peut s'avérer nécessaire de cliquer sur la barre d'informations, située dans la partie supérieure du concepteur, pour recharger la vue.

        <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. En mode Concepteur, sélectionnez le contrôle.

  5. Dans la fenêtre Propriétés, cliquez sur le bouton de déroulement situé en regard de la propriété Background. Un éditeur de couleurs visuel s'affiche en remplacement de la liste de couleurs par défaut.

  6. Sélectionnez une couleur dans l'éditeur. Cette couleur s'applique à l'arrière-plan du contrôle personnalisé.

Voir aussi

Tâches

Procédure pas à pas : implémentation d'un éditeur de valeurs inline

Comment : créer un éditeur de valeurs

Autres ressources

Création d'éditeurs personnalisés

Extensibilité du Concepteur WPF