2009-06-18 20 views
6

Estoy tratando de crear un UserControl reutilizable en WPF que tenga una etiqueta y un cuadro de texto. Deseo agregar propiedades a mi UserControl para hacer saltar los campos de texto de ambos controles secundarios hasta el elemento principal para facilitar el enlace. Leí que necesito un poco de hocus pocus al agregar propietarios a DependencyProperties. Aquí está mi código ahora. Parece cercano pero no del todo correcto. ¿Algunas ideas?Controles compuestos de WPF

Aquí es el Xaml:

<UserControl x:Class="MAAD.AircraftExit.Visual.LabelTextBox" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="20" Width="300"> 
    <DockPanel> 
     <TextBlock Text="{Binding Path=Label, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" DockPanel.Dock="Left" TextAlignment="Right" Width="122" /> 
     <TextBlock Text=": " DockPanel.Dock="Left"/> 
     <TextBox Text="{Binding Path=Text, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" /> 
    </DockPanel> 
</UserControl> 

Y el código subyacente:

public partial class LabelTextBox : UserControl 
{ 
    public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(LabelTextBox)); 
    public string Label 
    { 
     get { return (string)GetValue(LabelProperty); } 
     set { SetValue(LabelProperty, value); } 
    } 

    public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(LabelTextBox)); 
    public string Text 
    { 
     get { return (string)GetValue(TextProperty); } 
     set { SetValue(LabelTextBox.TextProperty, value); } 
    } 

    public LabelTextBox() 
    { 
     InitializeComponent(); 

     ClearValue(HeightProperty); 
     ClearValue(WidthProperty); 
    } 
} 

Editar: Aquí está el código de trabajo final. Cambié a la vinculación de fuente relativa.

+1

Intenté lo mismo al principio y asumí que de eso se trataba el concepto de propietario. Desafortunadamente, me encontré con los mismos problemas y terminé recurriendo al uso de enlaces también. Además, mis propiedades de no dependencia tienen una solución personalizada diferente para propagar notificaciones de cambio de propiedad. – jpierson

Respuesta

6

La unión es realmente el camino a seguir:

XAML:

<UserControl x:Class="testapp.LabelTextBox " 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Height="300" Width="300" x:Name="This"> 
<DockPanel> 
    <TextBlock DockPanel.Dock="Left" TextAlignment="Right" Width="70" Name="label" Text="{Binding Label, ElementName=This}" /> 
    <TextBlock Text=": " DockPanel.Dock="Left" /> 
    <TextBox Name="textBox" Text="{Binding Text, ElementName=This}" /> 
</DockPanel> 

código subyacente:

public partial class LabelTextBox : UserControl 
{ 
    public LabelTextBox() 
    { 
     InitializeComponent(); 
     Label = "Label"; 
     Text = "Text"; 
    } 
    public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(LabelTextBox), new FrameworkPropertyMetadata(LabelPropertyChangedCallback)); 
    private static void LabelPropertyChangedCallback(DependencyObject controlInstance, DependencyPropertyChangedEventArgs args) 
    { 
    } 
    public string Label 
    { 
     get { return (string) GetValue(LabelProperty); } 
     set { SetValue(LabelProperty, value); } 
    } 

    public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(LabelTextBox), new FrameworkPropertyMetadata(TextPropertyChangedCallback)); 
    private static void TextPropertyChangedCallback(DependencyObject controlInstance, DependencyPropertyChangedEventArgs args) 
    { 
    } 
    public string Text 
    { 
     get { return (string) GetValue(TextProperty); } 
     set { SetValue(LabelTextBox.TextProperty, value); } 
    } 
} 
+0

Gracias por el código, obtengo esta salida cuando intento usarlo: System.Windows.Data Error: 4: No se puede encontrar el origen del enlace con la referencia 'ElementName = This'. BindingExpression: Path = Label; DataItem = null; el elemento de destino es 'TextBlock' (Name = ''); La propiedad de destino es 'Texto' (escriba 'Cadena') –

+0

Disculpe, lo descubrí. Usted definió esto como el nombre del control. ¡¡Gracias!! –

1

No he investigado exactamente por qué su implementación no funciona, pero realmente no entiendo por qué lo hace de esa manera. ¿Por qué no simplemente definir las propiedades de dependencia que necesita en UserControl y luego vincularlas?

public static readonly DependencyProperty LabelTextProperty = ...; 

Y luego, en el XAML:

<Label Content="{Binding LabelText}"/>