c# - ¿El enlace XAML no funciona en la propiedad de dependencia?
wpf data-binding (1)
La declaración de propiedad de dependencia debe tener este aspecto:
public static readonly DependencyProperty TestProperty =
DependencyProperty.Register(
"Test", typeof(string), typeof(MyControl), new PropertyMetadata("DEFAULT"));
public string Test
{
get { return (string)GetValue(TestProperty); }
set { SetValue(TestProperty, value); }
}
El enlace en el XAML de UserControl debe establecer la instancia de control como el objeto fuente, por ejemplo, estableciendo la propiedad
RelativeSource
los enlaces:
<UserControl x:Class="WpfTest.MyControl" ...>
<TextBlock Text="{Binding Test,
RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</UserControl>
También es muy importante,
nunca
establezca el
DataContext
de un UserControl en su constructor.
Estoy seguro de que hay algo como
DataContext = this;
Elimínelo, ya que efectivamente evita heredar un DataContext del padre del UserConrol.
Al configurar
Source = DataContext
en el enlace en el código detrás, está configurando explícitamente una fuente de enlace, mientras que en
<local:MyControl Test="{Binding MyText}" />
la fuente de enlace implícitamente es el DataContext actual. Sin embargo, ese DataContext se ha establecido mediante la asignación en el constructor de UserControl al UserControl mismo, y no es el DataContext heredado (es decir, la instancia del modelo de vista) de la ventana.
Estoy intentando (y no puedo) hacer enlace de datos en una propiedad de dependencia en xaml. Funciona bien cuando uso el código detrás, pero no en xaml.
El control de usuario es simplemente un
TextBlock
que se une a la propiedad de dependencia:
<UserControl x:Class="WpfTest.MyControl" [...]>
<TextBlock Text="{Binding Test}" />
</UserControl>
Y la propiedad de dependencia es una cadena simple:
public static readonly DependencyProperty TestProperty
= DependencyProperty.Register("Test", typeof(string), typeof(MyControl), new PropertyMetadata("DEFAULT"));
public string Test
{
get { return (string)GetValue(TestProperty); }
set { SetValue(TestProperty, value); }
}
Tengo una propiedad regular con la implementación habitual de
INotifyPropertyChanged
en la ventana principal.
private string _myText = "default";
public string MyText
{
get { return _myText; }
set { _myText = value; NotifyPropertyChanged(); }
}
Hasta aquí todo bien.
Si asocio esta propiedad a un
TextBlock
en la ventana principal, todo funciona bien.
El texto se actualiza correctamente si
MyText
cambia y todo está bien en el mundo.
<TextBlock Text="{Binding MyText}" />
Sin embargo, si hago lo mismo en mi control de usuario, no pasa nada.
<local:MyControl x:Name="TheControl" Test="{Binding MyText}" />
¡Y ahora la parte divertida es que si hago el mismo enlace en el código detrás, funciona!
TheControl.SetBinding(MyControl.TestProperty, new Binding
{
Source = DataContext,
Path = new PropertyPath("MyText"),
Mode = BindingMode.TwoWay
});
¿Por qué no funciona en xaml?