Compartir a través de


Cómo: Crear un editor de valores de propiedad con cuadro de diálogo

En el ejemplo de código siguiente se muestra cómo se implementa un editor de valores de propiedad con un cuadro de diálogo personalizado en WPF Designer for Visual Studio. Para obtener una solución completa, vea el ejemplo Dialog Property Value Editor en el sitio WPF Designer Extensibility Samples

Ejemplo

En este tema se muestra cómo crear un editor de valores de propiedad con cuadro de diálogo que muestra un cuadro de diálogo de apertura de archivo cuando se hace clic en una propiedad FileName personalizada en la ventana Propiedades.

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>

Compilar el código

Compile el ejemplo de código anterior en tres ensamblados independientes.

Compilar el control personalizado

  1. En Visual Studio, cree un nuevo proyecto de biblioteca de controles de usuario de WPF en C# denominado CustomControlLibrary.

  2. Cambie todas las apariciones de "UserControl1" a "DemoControl".

  3. Reemplace el código existente en la clase DemoControl por el código indicado anteriormente.

  4. Genere la solución.

Compilar el editor de valores de propiedad con cuadro de diálogo personalizado

  1. En Visual Studio, agregue un nuevo proyecto de biblioteca de controles de usuario de WPF denominado CustomControlLibrary.Design a la solución.

  2. Establezca la ruta de acceso de salida del proyecto en ".. \CustomControlLibrary\bin\Debug\".

  3. Elimine UserControl1.xaml y UserControl1.xaml.cs del proyecto.

  4. Agregue referencias a los siguientes ensamblados.

    • Microsoft.Windows.Design.Extensibility

    • Microsoft.Windows.Design.Interaction

  5. Agregue una referencia al proyecto CustomControlLibrary.

  6. Agregue un diccionario de recursos denominado EditorResources al proyecto.

  7. Reemplace el XAML existente en EditorResources.xaml por el XAML citado anteriormente.

  8. Agregue al proyecto una nueva clase denominada EditorResources.

  9. Reemplace el código existente en EditorResources por el código indicado anteriormente.

  10. Agregue al proyecto una nueva clase denominada FileBrowserDialogPropertyValueEditor.

  11. Reemplace el código existente en la clase FileBrowserDialogPropertyValueEditor por el código indicado anteriormente.

  12. Agregue al proyecto una nueva clase denominada Metadata.

  13. Reemplace el código existente en la clase Metadata por el código indicado anteriormente.

  14. Genere la solución.

Compilar la aplicación de prueba

  1. En Visual Studio, agregue un nuevo proyecto de aplicación de WPF a la solución.

  2. Agregue una referencia al ensamblado o proyecto CustomControlLibrary.

  3. En la vista XAML de MainWindow.xaml, reemplace el XAML existente por el XAML mostrado anteriormente.

  4. En MainWindow.xaml.cs, marque como comentario la llamada a InitializeComponent.

  5. Vuelva a generar la solución.

  6. En la Vista de diseño, haga clic en DemoControl para seleccionarlo. Puede que tenga que hacer clic en la barra Información situada en la parte superior del diseñador para volver a cargar la vista.

  7. En la ventana Propiedades, haga clic en el botón situado junto a la propiedad FileName.

    Aparecerá el cuadro de diálogo Abrir.

  8. Navegue a un archivo y haga clic en Abrir.

    El nombre del archivo se muestra en la propiedad FileName de la ventana Propiedades y la propiedad FileName se asigna en la vista XAML.

Vea también

Referencia

ItemPolicy

PrimarySelectionPolicy

Otros recursos

Conceptos de extensibilidad avanzada

Extensibilidad de WPF Designer

WPF Designer Extensibility Samples