Condividi tramite


Procedura dettagliata: implementazione di un editor di colori

Il modello di estensibilità per WPF Designer per Visual Studio consente di creare in fase di progettazione editor di valori personalizzati per le proprietà nella finestra Proprietà. Gli editor possono essere editor in linea, che consentono di modificare i valori direttamente nella finestra Proprietà, o editor estesi, che consentono di fornire un'interfaccia utente aggiuntiva per modificare una proprietà al di fuori della finestra Proprietà. Per illustrare come creare un editor esteso, in questa procedura dettagliata vengono forniti i passaggi per la creazione di un editor di colori per la proprietà Background di un controllo. L'editor esteso viene aperto da un editor in linea nella finestra Proprietà.

Questa procedura dettagliata prevede l'esecuzione delle attività seguenti:

  • Creare il progetto di controllo personalizzato WPF.

  • Creare un controllo utente che si comporterà come l'editor esteso.

  • Creare un editor in linea che può essere utilizzato per modificare il valore di proprietà nella finestra Proprietà e aprire l'editor esteso.

  • Creare una classe che eredita da ExtendedPropertyValueEditor utilizzata per connettere gli editor alla classe per la quale si desidera fornire funzionalità di modifica personalizzate.

  • Creazione di una classe che implementa l'interfaccia IProvideAttributeTable per registrare il nuovo editor esteso.

  • Testare l'editor esteso in fase di progettazione.

Prerequisiti

Per completare la procedura dettagliata, è necessario disporre dei componenti seguenti:

  • Visual Studio 2010.

Creazione del controllo personalizzato

Il primo passaggio consiste nella creazione del progetto per il controllo personalizzato. Il controllo è un semplice pulsante con una piccola quantità di codice Design-Time che utilizza il metodo GetIsInDesignMode per implementare un comportamento in fase di progettazione.

Per creare il controllo personalizzato

  1. In Visual C# creare un nuovo progetto di libreria di controlli personalizzati WPF denominato CustomControlLibrary.

    Il codice per CustomControl1 verrà aperto nell'editor di codice.

  2. Nell'editor del codice per CustomControl1, sostituire il codice nello spazio dei nomi CustomControlLibrary con il codice seguente:

    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. Impostare il percorso di output del progetto su "bin\".

  4. Compilare la soluzione.

Creazione di un controllo utente per l'editor esteso

Il controllo creato nella procedura precedente è il controllo al quale verrà allegato l'editor di colori personalizzato. In questa procedura, verrà creato un altro controllo utente che si comporterà come l'editor esteso.

Per creare un controllo utente che si comporti come l'editor esteso

  1. In Visual C# aggiungere alla soluzione un nuovo progetto di libreria di controlli personalizzati WPF denominato CustomControlLibrary.Design.

    Il codice per CustomControl1 verrà aperto nell'editor del codice.

  2. In Esplora soluzioni eliminare il file CustomControl1 dal progetto CustomControlLibrary.Design.

  3. Aggiungere un riferimento ai seguenti assembly di WPF Designer.

    • Microsoft.Windows.Design.Extensibility

    • Microsoft.Windows.Design.Interaction

  4. Aggiungere un riferimento al progetto CustomControlLibrary.

  5. Impostare il percorso di output del progetto su ".. \CustomControlLibrary\bin\". In questo modo l'assembly del controllo e l'assembly dei metadati verranno mantenuti nella stessa cartella, consentendo l'individuazione di metadati per le finestre di progettazione.

  6. Aggiungere una nuova classe denominata ColorsList al progetto CustomControlLibrary.Design.

  7. Nell'editor del codice per ColorsList sostituire il codice generato automaticamente con il codice seguente.

    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. Aggiungere un nuovo controllo utente (WPF) denominato ColorsListControl al progetto CustomControlLibrary.Design.

    Il codice per ColorsListControl.xaml verrà aperto nella finestra di progettazione.

  9. In visualizzazione XAML per ColorsListControl.xaml, sostituire il codice XAML generato automaticamente con il codice XAML seguente.

        <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. In Esplora soluzioni espandere ColorsListControl.xaml e aprire ColorsListControl.xaml.cs.

  11. Nell'editor del codice per ColorsListControl sostituire il codice generato automaticamente con il codice seguente.

    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. Compilare la soluzione.

  13. Ricaricare ColorsListControl.xaml nella finestra di progettazione. In visualizzazione Progettazione verrà visualizzata l'interfaccia utente dell'editor esteso.

Creazione di modelli per l'editor di colori

L'editor in linea per l'editor di colori è meno complesso dell'editor esteso e può essere creato con un modello di dati XAML. Verrà creato anche un modello di dati per l'editor esteso che specifica come utilizzare il controllo utente creato nella procedura precedente.

Per creare un modello per l'editor di colori

  1. Aggiungere una nuova classe denominata EditorResources al progetto CustomControlLibrary.Design.

  2. Nell'editor del codice per EditorResources sostituire il codice generato automaticamente con il codice seguente.

    namespace ExtendedEditorNamespace
    {
        using System;
        using System.Collections.Generic;
        using System.Text;
        using System.Windows;
        public partial class EditorResources : ResourceDictionary {
            public EditorResources()
                : base()
            {
                InitializeComponent();
            }
        }
    }
    
  3. Scegliere Aggiungi dizionario risorse dal menu Progetto.

  4. Denominare il file EditorResources.xaml e fare clic su Aggiungi.

    Il codice per EditorResources.xaml verrà visualizzato nella finestra di progettazione.

  5. In visualizzazione XAML per il file EditorResources.xaml, sostituire il codice XAML generato automaticamente con il codice XAML seguente.

        <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. Compilare la soluzione.

Incapsulamento dei modelli e registrazione degli editor

La parte più faticosa del lavoro è finita. Una volta creati i modelli degli editor estesi e in linea per l'editor di colori, è possibile incapsularli in una classe creata appositamente e registrarli con il controllo personalizzato.

Per incapsulare e registrare gli editor

  1. Aggiungere una nuova classe denominata BrushExtendedEditor al progetto CustomControlLibrary.Design.

  2. Nell'editor del codice per BrushExtendedEditor sostituire il codice generato automaticamente con il codice seguente.

    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. Aggiungere una nuova classe denominata Metadata al progetto CustomControlLibrary.Design.

  4. Nell'editor del codice per Metadata sostituire il codice generato automaticamente con il codice seguente.

    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. Compilare la soluzione.

Verifica dell'editor di colori

È stata appena completata la creazione dell'editor di colori. Resta solo da verificarne il funzionamento. Per verificare l'editor verrà aggiunto un progetto di applicazione WPF alla soluzione e verrà aggiunto il controllo personalizzato. Verrà quindi modificata la proprietà Background nella finestra Proprietà e sarà possibile vedere il nuovo editor in azione.

Per verificare l'editor di colori

  1. In Visual C# aggiungere alla soluzione un nuovo progetto di applicazione WPF denominato DemoApplication.

    MainWindow.xaml viene aperto in WPF Designer.

  2. Aggiungere un riferimento al progetto CustomControlLibrary.

  3. In visualizzazione XAML per MainWindow.xaml sostituire il codice XAML generato automaticamente con il codice XAML seguente. Con questo codice XAML viene aggiunto un riferimento allo spazio dei nomi CustomControlLibrary e viene aggiunto il controllo personalizzato CustomControl1. Il pulsante appare in visualizzazione Progettazione con lo sfondo rosso a indicare che il controllo è nella modalità progettazione. Se il pulsante non viene visualizzato, può essere necessario fare clic sulla barra informazioni nella parte superiore della finestra di progettazione per ricaricare la visualizzazione.

        <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. In visualizzazione Progettazione selezionare il controllo.

  5. Nella finestra Proprietà fare clic sul pulsante a discesa posto accanto alla proprietà Background. Verrà visualizzato un editor di colori visivo anziché l'elenco predefinito di colori.

  6. Selezionare un colore dall'editor. Il colore di sfondo del controllo personalizzato cambierà in base al colore selezionato.

Vedere anche

Attività

Procedura dettagliata: implementazione di un editor di valori inline

Procedura: creare un editor di valori

Altre risorse

Creazione di editor personalizzati

Estensibilità di Progettazione WPF