2010-07-16 20 views
10

Tengo un UserControl que deseo participar en el enlace de datos. Establecí las propiedades de dependencia en el control de usuario, pero no puedo hacer que funcione.Enlace de datos a un UserControl en WPF

La UC muestra el texto correcto cuando lo llamo con texto estático (por ejemplo, BlueText = "ABC"). Cuando intento vincularlo a una propiedad pública local, siempre está en blanco.

<src:BlueTextBox BlueText="Feeling blue" />   <!--OK--> 
<src:BlueTextBox BlueText="{Binding Path=MyString}" /> <!--UserControl always BLANK!--> 
<TextBox Text="{Binding Path=MyString}" Width="100"/> <!--Simple TextBox Binds OK--> 

He hervido el código en el siguiente ejemplo simplificado. Aquí está el código XAML del UserControl:

<UserControl x:Class="Binding2.BlueTextBox" ... 
    <Grid> 
     <TextBox x:Name="myTextBox" Text="{Binding BlueText}" Foreground="Blue" Width="100" Height="26" /> 
    </Grid> 

Aquí está el código detrás del control de usuario:

public partial class BlueTextBox : UserControl 
{ 
    public BlueTextBox() 
    { 
     InitializeComponent(); 
     DataContext = this; // shouldn't do this - see solution 
    } 

    public static readonly DependencyProperty BlueTextProperty = 
     DependencyProperty.Register("BlueText", typeof(string), typeof(BlueTextBox)); 

    public string BlueText 
    { 
     get { return GetValue(BlueTextProperty).ToString(); } 
     set { SetValue(BlueTextProperty, value.ToString()); } 
    } 

Esta parece que debería ser muy fácil, pero no puedo hacer que funcione. ¡Gracias por tu ayuda!

Más información: Cuando estaba probando la solución sugerida por Eugene, noté un comportamiento peculiar. Agregué un PropertyChangedCallback a los metadatos; esto me permite observar el valor de BlueText. Al establecer la cadena en un valor estático (= "se siente azul") se activa el evento PropertyChanged. El caso de enlace de datos no activa PropertyChanged. Creo que esto significa que el valor vinculado a los datos no se envía al UserControl. (Creo que el constructor no recibe llamadas en el caso estático)

Solución: Los problemas fueron identificados correctamente por Arcturus y jpsstavares. En primer lugar, estaba sobrescribiendo el enlace de datos cuando se establece DataContext = this en el constructor del control. Esto evitó que se estableciera el valor enlazado a datos. También tuve que nombrar el control x: Name = root, y especificar el nombre de elemento de enlace = root int el XAML. Para obtener el enlace de TwoWay, necesitaba establecer Mode = TwoWay en la persona que llama. Aquí está el código correcto:

<src:BlueTextBox BlueText="{Binding Path=MyString, Mode=TwoWay}}" /> <!--OK--> 

Ahora el XAML en el control de usuario:

<UserControl x:Class="Binding2.BlueTextBox" x:Name="root"... 
    <Grid> 
     <TextBox x:Name="myTextBox" Text="{Binding ElementName=root, Path=BlueText}" Foreground="Blue" Width="100" Height="26" /> 
    </Grid> 

Finalmente quité el DataContext = esta en el constructor del control de usuario.

public BlueTextBox() 
    { 
     InitializeComponent(); 
     //DataContext = this; -- don't do this 
    } 

Gracias a todos por la gran ayuda!

Respuesta

11

Se establece el DataContext en el control de sí mismo, sobrescribiendo así el DataContext al utilizar este control en otros controles. Llevar a su unión como ejemplo en su situación:

<src:BlueTextBox BlueText="{Binding Path=MyString}" /> 

Una vez cargado y todo el DataContext se establece, se buscará la ruta MiCadena en su control BlueTextBox cosa, debido a que el establecimiento de la DataContext a ella. Supongo que no es así como intentaste que esto funcione;).

Solución:

cambiar el enlace, ya sea uno de los 2 enlaces de texto:

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:BlueTextBox}}, Path=BlueText} 

o

Nombre raíz de su control (o algo así)

<UserControl x:Name="Root" 

{Binding ElementName=Root, Path=BlueText} 

Y eliminar el

DataContext = this; 

desde el constructor de su UserControl y debería funcionar como un encanto ..

2

Creo que en este caso es necesario para establecer la propiedad ElementName en la unión. Algo como esto:

<UserControl x:Class="Binding2.BlueTextBox" x:Name="blueTextBox"... 
<Grid> 
    <TextBox x:Name="myTextBox" Text="{Binding ElementName=blueTextBox, Path=BlueText}" Foreground="Blue" Width="100" Height="26" /> 
</Grid> 
0

Sé que esto es un viejo tema, pero todavía.

también mencionar el PropertyChangedCallback en el UIPropertyMetadata durante el registro de su DP

Cuestiones relacionadas