2012-04-17 10 views
6

Cuando tienes un usercontrol en wpf, ¿puede llegar afuera a sus elementos principales? Por ejemplo, mi control de usuario solo enumera algunos elementos genéricos que se guardan dentro del control que está encapsulado dentro de un panel acoplable en la ventana principal, pero tengo un cuadro de texto y un botón en la ventana principal a los que me gustaría acceder desde el control ... ¿es posible?UserControl utilizando elementos principales en wpf?

Me ahorraría mucho tiempo en lugar de cambiar el contenido de toda la ventana y mostrar el mismo cuadro de texto/botón en cada control de usuario. Si alguien tiene un ejemplo de esto, sería muy apreciado.

+0

echó otro vistazo a esto - que han intentado acceder a los elementos primarios con DataBinding y un RelativeSource de ancestro? Aquí hay una buena [respuesta SO] (http://stackoverflow.com/questions/84278/how-do-i-use-wpf-bindings-with-relativesource) si es así. Si eso no parece una buena solución, puede publicar un código para ilustrar el problema. Cheers – Berryl

Respuesta

3

Sí, es posible y aquí hay un código que he usado para componer presentaciones de UserControls que tienen DP.

No me gusta ni siquiera un poco, pero funciona. También creo que este es un gran tema y tal vez algún código ayudará a obtener mejores respuestas.

Saludos,
Berry

control de usuario XAML

<Button x:Name="btnAddNewItem" Style="{StaticResource blueButtonStyle}" > 
    <StackPanel Orientation="Horizontal"> 
     <Image Source="{resx:Resx ResxName=Core.Presentation.Resources.MasterDetail, Key=bullet_add}" Stretch="Uniform" /> 
     <Label x:Name="tbItemName" Margin="5" Foreground="White" Padding="10, 0">_Add New [item]</Label> 
    </StackPanel> 
</Button> 

Código UserControl Detrás

public partial class AddNewItemButton : UserControl 
{ 
    ... 

    #region Item Name 

    public static readonly DependencyProperty ItemNameProperty = DependencyProperty.Register(
     "ItemName", typeof(string), typeof(AddNewItemButton), 
     new FrameworkPropertyMetadata(OnItemNameChanged)); 

    public string ItemName 
    { 
     get { return (string)GetValue(ItemNameProperty); } 
     set { SetValue(ItemNameProperty, value); } 
    } 

    public string ButtonText { get { return (string) tbItemName.Content; } } 

    private static void OnItemNameChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 
    { 
     // When the item name changes, set the text of the item name 
     var control = (AddNewItemButton)obj; 

     control.tbItemName.Content = string.Format(GlobalCommandStrings.Subject_Add, control.ItemName.Capitalize()); 
     control.ToolTip = string.Format(GlobalCommandStrings.Subject_Add_ToolTip, control.ItemName); 
    } 

    #endregion 

    #region Command 

    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
     "Command", typeof(ICommand), typeof(AddNewItemButton), 
     new FrameworkPropertyMetadata(OnCommandChanged)); 

    public ICommand Command 
    { 
     get { return (ICommand)GetValue(CommandProperty); } 
     set { SetValue(CommandProperty, value); } 
    } 

    private static void OnCommandChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 
    { 
     // When the item name changes, set the text of the item name 
     var control = (AddNewItemButton)obj; 
     control.btnAddNewItem.Command = control.Command; 
    } 

    #endregion 

} 

enter image description here

Otra control de usuario mostrando Composición

<UserControl ... 
     xmlns:uc="clr-namespace:Smack.Core.Presentation.Wpf.Controls.UserControls" 
     > 

    <DockPanel LastChildFill="True"> 
     ... 
     <uc:AddNewItemButton x:Name="_addNewItemButton" Margin="0,0,10 0" DockPanel.Dock="Right" /> 
     ... 
    </DockPanel> 
</UserControl> 

enter image description here

+1

Pregunta simple, respuesta WTF. –

+1

@Berryl +10 en respuesta! Gran esfuerzo y gracias! –

+1

@KendallFrey. No es * tan * simple cuando lo piensas, pero si es solo para ti, publica un código simple y claro para presentar tu caso. – Berryl

3

Un mejor patrón de diseño sería hacer que el control de usuario notifique (a través del evento) la ventana principal cuando algo necesita ser cambiado, y preguntar a la ventana (a través del método) cuándo necesita alguna información. Tendría, por ejemplo, un método GetText() en la ventana que podría llamar el control de usuario, y un evento ChangeText en el control de usuario al que la ventana se suscribiría.

La idea es mantener la ventana bajo control en todo momento. Usar esta mentalidad le facilitará desarrollar aplicaciones en el futuro.

+0

Entonces, usando su ejemplo, si tuviera un cuadro de texto y un botón, ¿cómo enviaría el texto al control de usuario y luego llenaría ese control con el botón de texto al hacer clic? –

+0

Crea un método en usercontrol (digamos, 'SetText (string text)'). En 'button1_Click', llama a' myUserControl.SetText (myTextBox.Text) '.En el método 'SetText' en usercontrol, puede hacer lo que quiera para completar los datos en el control de usuario. –

2

Para responder a su pregunta: sí, puede acceder a los controles principales a través de un enlace RelativeSource o mediante el miembro principal en el código posterior. Pero una mejor respuesta es similar a la respuesta de @KendallFrey. Adopte un marco como Light MVVM y use su clase de mensajería o use eventos de la forma descrita por Kendall.

Cuestiones relacionadas