Procedura: creare un editor di valori di proprietà di una finestra di dialogo

Nell'esempio di codice seguente viene mostrato come implementare un editor di valori di proprietà personalizzato di una finestra di dialogo per WPF Designer per Visual Studio. Per una soluzione completa, vedere l'esempio di editor di valori di proprietà di una finestra di dialogo nel sito Esempi di estensibilità di WPF Designer

Esempio

In questo argomento viene illustrato come creare un editor di valori di proprietà di una finestra di dialogo che consenta di visualizzare una finestra di dialogo di apertura file quando nella finestra Proprietà viene selezionata una proprietà FileName personalizzata.

using System;
using System.ComponentModel;
using System.Windows.Controls;
using System.Windows;

namespace CustomControlLibrary
{
    public partial class DemoControl : UserControl
    {
        public DemoControl()
        {
            InitializeComponent();
        }

        public static readonly DependencyProperty FileNameProperty = DependencyProperty.Register(
            "FileName", 
            typeof(string), 
            typeof(DemoControl), 
            new PropertyMetadata("File name not set."));

        public string FileName
        {
            get
            {
                return (string)this.GetValue(FileNameProperty);
            }

            set
            {
                this.SetValue(FileNameProperty, value);
            }
        }
    }
}
<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"
                    x:Class="CustomControlLibrary.Design.EditorResources">

    <DataTemplate x:Key="FileBrowserInlineEditorTemplate">
        <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>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CustomControlLibrary.Design
{
    using System.Windows;
    public partial class EditorResources : ResourceDictionary
    {
        public EditorResources()
            : base()
        {
            InitializeComponent();
        }
    }
}
using System;
using System.ComponentModel;
using System.Windows;
using Microsoft.Windows.Design.Metadata;
using Microsoft.Windows.Design.PropertyEditing;
using Microsoft.Win32;

namespace CustomControlLibrary.Design
{
    public class FileBrowserDialogPropertyValueEditor : DialogPropertyValueEditor
    {
        private EditorResources res = new EditorResources();

        public FileBrowserDialogPropertyValueEditor()
        {
            this.InlineEditorTemplate = res["FileBrowserInlineEditorTemplate"] as DataTemplate;
        }

        public override void ShowDialog(
            PropertyValue propertyValue,
            IInputElement commandSource)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Multiselect = false;

            if (ofd.ShowDialog() == true)
            {
                propertyValue.StringValue = ofd.FileName;
            }
        }
    }
}
using System;
using System.ComponentModel;
using System.Windows;
using Microsoft.Windows.Design.Metadata;
using Microsoft.Windows.Design.PropertyEditing;

// 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(CustomControlLibrary.DemoControl),
                    "FileName",
                    PropertyValueEditor.CreateEditorAttribute(
                        typeof(FileBrowserDialogPropertyValueEditor)));

                return builder.CreateTable();
            }
        }
    }
}
<Window x:Class="WpfApplication1.MainWindow"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ccl="clr-namespace:CustomControlLibrary;assembly=CustomControlLibrary"
    Title="MainWindow" Height="300" Width="300">
    <Grid>
        <ccl:DemoControl FileName="" />
    </Grid>
</Window>

Compilazione del codice

Compilare il codice dell'esempio precedente in tre assembly distinti.

Compilazione del controllo personalizzato

  1. In Visual Studio, creare un nuovo progetto di libreria di controlli utente WPF in C# denominato CustomControlLibrary.

  2. Modificare tutte le occorrenze di "UserControl1" in "DemoControl".

  3. Sostituire il codice esistente nella classe DemoControl con il codice indicato in precedenza.

  4. Compilare la soluzione.

  1. In Visual Studio aggiungere alla soluzione un nuovo progetto di libreria di controlli utente WPF denominato CustomControlLibrary.Design.

  2. Impostare il percorso di output del progetto su ".. \CustomControlLibrary\bin\".

  3. Eliminare UserControl1.xaml e UserControl1.xaml.cs dal progetto.

  4. Aggiungere riferimenti agli assembly riportati di seguito.

    • Microsoft.Windows.Design.Extensibility

    • Microsoft.Windows.Design.Interaction

  5. Aggiungere un riferimento al progetto CustomControlLibrary.

  6. Aggiungere al progetto un dizionario risorse denominato EditorResources.

  7. Nel file EditorResources.xaml sostituire il codice XAML esistente con quello indicato in precedenza.

  8. Aggiungere al progetto una nuova classe denominata EditorResources.

  9. Sostituire il codice esistente nella classe EditorResources con il codice indicato in precedenza.

  10. Aggiungere al progetto una nuova classe denominata FileBrowserDialogPropertyValueEditor.

  11. Sostituire il codice esistente nella classe FileBrowserDialogPropertyValueEditor con il codice indicato in precedenza.

  12. Aggiungere al progetto una nuova classe denominata Metadata.

  13. Sostituire il codice esistente nella classe Metadata con il codice indicato in precedenza.

  14. Compilare la soluzione.

Compilazione dell'applicazione di test

  1. In Visual Studio, aggiungere un nuovo progetto di applicazione WPF alla soluzione.

  2. Aggiungere un riferimento all'assembly o progetto CustomControlLibrary.

  3. In visualizzazione XAML per il file MainWindow.xaml, sostituire il codice XAML esistente con il codice XAML indicato in precedenza.

  4. Nel file MainWindow.xaml.cs, impostare come commento la chiamata all'oggetto InitializeComponent.

  5. Ricompilare la soluzione.

  6. In visualizzazione Progettazione, fare clic sull'oggetto DemoControl per selezionarlo. Potrebbe essere necessario fare clic sulla barra informazioni nella parte superiore della finestra di progettazione per ricaricare la visualizzazione.

  7. Nella finestra Proprietà, fare clic sul pulsante accanto alla proprietà FileName.

    Verrà visualizzata la finestra di dialogo Apri.

  8. Individuare un file, quindi scegliere Apri.

    Il nome del file viene visualizzato nella proprietà FileName della finestra Proprietà e la proprietà FileName viene assegnata nella visualizzazione XAML.

Vedere anche

Riferimenti

ItemPolicy

PrimarySelectionPolicy

Altre risorse

Concetti avanzati sulla estensibilità

Estensibilità di Progettazione WPF

Esempi di estensibilità di WPF Designer