Ir al contenido principal

[Silverlight] Hacer binding a las propiedades de un UserControl

Hola a todos.

Ahora voy a explicar un problema que me ha surgido hace unos días y me gustaría compartir por si alguna vez os encontráis en la misma situación.

Escenario:
Tenemos un proyecto en Silverlight y hemos creado un UserControl porque lo vamos a utilizar en mas de una vista y no vamos a duplicar el código.

Problema 1: ¿Cómo comunico los datos de mi UserControl con el exterior?

En este caso, creamos una Dependency Property por cada uno de los campos que queremos "comunicar"


private DependencyProperty UserNameProperty =
            DependencyProperty.Register("UserName", typeof(string), typeof(UserForm), new PropertyMetadata(string.Empty));

Luego definimos una property pública para enlazar esta Dependecy Property:

[System.ComponentModel.Category("User properties")]
[System.ComponentModel.Description("User Name")]
public string UserName
{
     get { return (string)GetValue(UserNameProperty); }
     set { SetValue(UserNameProperty, value); }
}

Hasta aquí es lo esperado...
Pero en el XAML tenemos que hacer binding contra estas propiedades, lo que hacemos es definir como DataContext a si mismo.

<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
x:Class="KurroSoftware.UserControls.UserForm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
d:DesignHeight="27" d:DesignWidth="505">

y nuestros campos hacemos el binding como siempre:
<TextBox x:Name="UserNameval" 
                 HorizontalAlignment="Stretch"
                 VerticalAlignment="Top" 
                 Text={Binding UserName, Mode=TwoWay}/>

Si ponemos nuestro UserControl en una ventana de Silverlight, y aplicamos los valores a estas propiedades, estas aparecen en nuestro control, 

        <my:UserForm HorizontalAlignment="Stretch" 
                     Name="userForm1" 
                     VerticalAlignment="Top" 
                     UserName="{Binding Mode=TwoWay, Path=UserName}"
                     Address="{Binding Mode=TwoWay, Path=Address}" 
                     Phone="{Binding Mode=TwoWay, Path=Phone }" />

El gran problema está en que aunque hemos definido como TwoWay, esto no modifica la propiedad en nuestro DataContext.
Esto tiene una sencilla explicación.
Como hemos definido en nuestro UserControl el DataContext a si mismo, para poder leer los valores de las propias propiedades, no existe una comunicación con el DataContext de la ventana contenedora, pues para él esta definido de forma egoísta.
Esto tiene fácil solución.
En lugar de definir el DataContext y hacemos el binding en el XAML, lo hacemos en el CodeBehind, definiendo mediante C#. 

UserNameval.SetBinding(TextBox.TextProperty, new Binding() { Source = this, Mode = BindingMode.TwoWay, Path = new PropertyPath("UserName") });
            
El resultado es el mismo, pero el XAML no esta definiendo el DataContext, por lo que adoptará el de la ventana donde coloquemos el control.

Osea, que quitamos la definición del DataContext del inicio y la instrucción de Binding de nuestro TextBox, porque ya lo hacemos en el CodeBehind.

De esta forma existe una real comunicación de nuestro control con nuestra ventana host y sus propiedades.

El ejemplo, como siempre, a continuación en el siguiente enlace.

Espero tus comentarios.



Comentarios

Entradas populares de este blog

[VB] - Generar GUID

Esta si es buena... Como se nota que VB es un lenguaje con "solera", es decir, con años pero con robustez. Pero le pasa como al abuelo Cebolleta, tiene experiencia pero para los nuevos tiempos... ains.. le falta algo. Hoy en dia no sabriamos hacer nada sin un buen GUID, sobre todo si lo que queremos es identificar de forma unica y constante algun registro, objeto u otro componente. Usando SQL podemos generar un GUID en un santiamen a traves de la instrucción NEWID() , podemos crear un nuevo GUID en .NET usando la clase GUID.. pero... como lo hacemos con Visual Basic 6? Para empezar, vamos a ver en que se compone un GUID ¿Que es un GUID? Su significado es Globally Unique Identifier, osea Identificador globalmente único. Y su misión es la de proporcionar un identificador, de forma que es practicamente imposible que existan dos iguales en el mundo. Se compone de una palabra de 4 bytes, 3 palabras de 2 bytes y una de 6 bytes. Originalmente fue una idea de Microsoft pa...

[.NET] Convertir Latitud y Longitud en Grados - Minutos y segundos

Hola a todos. Esta es una función para convertir un número de posición geográfica en grados, minutos y segundos. Como algunos pocos recordarán,una posición geográfica esta definida por latitud (Norte / Sur) y longitud (Este / Oeste) teniendo como referencia para la longitud el meridiano de Greenwich (Meridiano 0) y para la latitud la linea del Ecuador (Paralelo 0). Por lo que siempre hablaremos de posición " Grados Norte ", o " Grados Este ". Ahora es cuando entra en juego las matemáticas y la trigonometría (he de admitir que me encantan :D ). El hemisferio norte o sur solo tendría 90° Norte o Sur. Por ejemplo, El polo norte está a 90° 0' 0'' N de latitud. La longitud podríamos considerar el 0° 0' 0'' (estamos en el polo norte, por lo que es un solo punto, no hay longitud). En cambio, si nos movemos alrededor de la tierra por la linea de Ecuador, la latitud será 0° 0' 0'' (ni al norte, ni al sur) pero de Este a Oeste nos m...