martes, 20 de abril de 2010

Extender Propiedades de un Control en WPF

Continuando con el trabajo sobre WPF, he tenido la necesidad de extender las propiedades de los User Controls que he ido creando, con el objetivo de que estos se ajustaran todavía más a mis necesidades.

Para ello, tenemos varias opciones en la siguiente web, con código para poder ver algunos ejemplos:

http://blogs.msdn.com/wpfsdk/archive/2009/09/16/wpf-designer-sample-code-is-posted.aspx

De entre todas ellas, me decidí por la que se llama: "Custom Dialog Property Value Editor", que consiste en añadir una propiedad nueva a tu control y crear un diálogo para controlarla



Aunque existe un ejemplo que podemos descargarnos en la web que he puesto antes, he preferido hacer un pequeño tutorial para los novatos como yo, con la finalidad de hacerlo más comprensible, puesto que al menos a mí me ha parecido algo complicado crear las propiedades desde cero.


Paso 1: Definir un User Control

Para empezar definimos un User Control, en el que introducimos un Textbox, que será lo que veamos al final en nuestra aplicación.

En la parte de código de nuestro User Control, definimos la propiedad que vamos a crear:

Código:

public int EnteroPrueba

{

get { return (int)GetValue(EnteroPruebaProperty); }

set { SetValue(EnteroPruebaProperty, value); }

}

// Using a DependencyProperty as the backing store for EnteroPrueba. This enables animation, styling, binding, etc...

public static readonly DependencyProperty EnteroPruebaProperty =

DependencyProperty.Register("EnteroPrueba", typeof(int), typeof(UserControl1), new UIPropertyMetadata(0));



Como veis el nombre de la propiedad es EnteroPrueba, y el tipo Entero, este tipo de propiedad es una Dependency Property, y la forma más fácil de definirla es con la plantilla que trae Visual Studio, para acceder a ella simplemente escribimos "propdp" y tabulamos.


Paso 2: Definimos el archivo Metadata, dentro del Diseño de la Propiedad

Esta parte es quizás la más complicada de todas, o al menos la que más me ha llevado, puesto que el concepto de crear la clase Metadata era nuevo para mí. Para ello, me he servido de esta web: http://msdn.microsoft.com/en-us/library/ee849819.aspx


En la clase Metadata lo que hacemos es definir un CustomAttribute que se añade a las propiedades del UserControl, así como definir cómo se va a modificar


Código:

[assembly: ProvideMetadata(typeof(PruebaControl.Design.Metadata))]

namespace PruebaControl.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(PruebaControl.UserControl1),

"EnteroPrueba",

PropertyValueEditor.CreateEditorAttribute(

typeof(FileBrowser)));

return builder.CreateTable();

}

}

}

}


Paso 3: Definir el Diccionario de Recursos


Esta parte es sencilla, simplemente definimos un diccionario de recursos, en el que elegiremos que es lo que queremos que se nos muestre a la hora de modificar la propiedad en el menú de abajo a la derecha.

No os olvidéis de crear el archivo .cs también.

Código XAML

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:PropertyEditing="clr-namespace:Microsoft.Windows.Design.PropertyEditing;assembly=Microsoft.Windows.Design.Interaction"

xmlns:custom="clr-namespace:PruebaControl.Design"

x:Class="PruebaControl.Design.EditResources">

<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>


Paso 4: Definición del FileBrowser

Esta clase lo que hace es definir como quiero modificar la propiedad que acabo de crear, es decir nos aporta la funcionalidad a lo que hemos creado en el paso anterior.

¡Aviso!

El código de este apartado no es mío, así que no me hago responsable de él, este código es para si queremos definir una propiedad string mediante un dialogo, es decir el ejemplo de MSDN, lo pongo aquí porque me parece que es necesario completar la información. Como veréis al final, mi propiedad no tiene un botoncito al final para abrir ningún cuadro de diálogo.


Código:

namespace CustomControlLibrary.Design

{

public class FileBrowser : DialogPropertyValueEditor

{

private EditResources res = new EditResources();

public FileBrowser()

{

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;

}

}

}

}


Paso 5: Crear una aplicación de Prueba

Este es el último paso de todos, tanto los que habéis seguido mi ejemplo al pie de la letra, como los que han decidido crear un string y utilizar el código del cuadro de diálogo, si todo está correcto llegaréis aquí. He creado una aplicación nueva, y he añadido desde la paleta el UserControl que acabamos de crear, en él, me he ido a la pestaña de Other Properties, y como podéis observar me aparece "EnteroPrueba", lista para que le diga un valor.

Una de las cosas interesantes de estas propiedades es que como otras se les puede vincular directamente con un DataBinding o con un Resource.

Conclusión:

Espero que este tutorial os haya sido de utilidad, he de dar las gracias al señor Ángel Acha, puesto que sin su ayuda y su comprensión, no habría logrado entender algunos conceptos, siempre consigue ponerte en el camino correcto, aunque no entienda muy bien de que le estás hablando y tú no se lo sepas explicar, que es lo que casi siempre le pasa xD, así que ¡Muchas Gracias!


Un saludo

MtCantero


PD: Próximamente, más posts sobre WPF.


No hay comentarios:

Publicar un comentario