2012-04-17 15 views
6

Kiedy masz kontrolę użytkownika w wpf, może ona dotrzeć poza jej elementy nadrzędne? Na przykład moja kontrola użytkownika zawiera listę ogólnych rzeczy, które są przechowywane wewnątrz kontrolki, która jest zamknięta wewnątrz panelu pomocniczego w głównym oknie, ale mam pole tekstowe i przycisk w głównym oknie, do którego chciałbym uzyskać dostęp z poziomu kontroli ... czy to możliwe?UserControl przy użyciu elementów macierzystych w wpf?

Zaoszczędziłoby mi to dużo czasu, zamiast zmieniać zawartość całego okna i wyświetlać ten sam tekst/przycisk w każdym sterowaniu użytkownika. Jeśli ktoś ma taki przykład, będzie to bardzo cenne.

+0

raz jeszcze spojrzeć na to - czy próbowałeś dostępu elementy rodzic z DataBinding i RelativeSource z przodka? Oto dobra [odpowiedź] (http://stackoverflow.com/questions/84278/how-do-i-use-wpf-bindings-withrelationsource), jeśli tak. Jeśli to nie wydaje się być dobrym rozwiązaniem, możesz napisać trochę kodu, aby zilustrować problem. Pozdrowienia – Berryl

Odpowiedz

3

Tak, jest to możliwe i tutaj jest kod, którego użyłem do komponowania prezentacji z UserControls, które mają DP.

Nie kocham tego nawet trochę, ale działa. Myślę też, że jest to temat wielki i może jakiś kod pomoże uzyskać lepsze odpowiedzi!

Cheers,
Berry

UserControl 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> 

Kod UserControl Za

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

Innym UserControl pokazując Skład

<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

Proste pytanie, odpowiedź WTF. –

+1

@Berryl +10 w odpowiedzi! Wielki wysiłek i dziękuję! –

+1

@KendallFrey. Nie jest * to * proste, gdy o tym myślisz, ale jeśli to do ciebie, po prostu załóż jakiś prosty i jasny kod, aby zrobić swoją sprawę. – Berryl

3

Lepszy wzorzec projektowy polegałby na powiadamianiu użytkownika (poprzez zdarzenie) o oknie głównym, gdy coś musi zostać zmienione, i zapytaniu o okno (za pośrednictwem metody), kiedy potrzebuje pewnych informacji. Miałbyś na przykład metodę GetText() w oknie, które może kontrolować użytkownik, oraz zdarzenie ChangeText w kontrolce użytkownika, do której będzie subskrybować okno.

Chodzi o to, aby cały czas kontrolować okno. Korzystanie z tej mentalności ułatwi tworzenie aplikacji w przyszłości.

+0

Więc używając swojego przykładu, jeśli miałeś pole tekstowe i przycisk, w jaki sposób wysłałbyś tekst do kontrolki użytkownika, a następnie wypełniłbyś tę kontrolkę tekstem na przycisku? –

+0

Utwórz metodę na kontrole użytkownika (powiedz: "SetText (tekst ciągu)"). W 'button1_Click', wywołaj' myUserControl.SetText (myTextBox.Text) '.W metodzie "SetText" w sterowaniu użytkownika możesz zrobić, co chcesz, aby dane były wypełniane w sterowaniu użytkownika. –

2

Aby odpowiedzieć na pytanie: tak, można uzyskać dostęp do kontroli rodzica poprzez powiązanie RelativeSource lub przez członka nadrzędnego w tylnym kodzie. Ale lepsza odpowiedź jest podobna do odpowiedzi @KendallFrey. Przyjmij framework, taki jak Light MVVM i użyj jego klasy komunikatora lub użyj zdarzeń w sposób opisany przez Kendall.

Powiązane problemy