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));
<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">
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.
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
Publicar un comentario
Si quieres comentar, criticar, aportar mas informacion o simplemente felicitar, inserta tu comentario a continuacion. Entre todos podemos hacer cosas grandes.