6

When you have a usercontrol in wpf can it reach outside to its parent elements? For instance my user control just lists some generic things which are held inside the control which is encapsulated within a dockpanel on the main window, but I have a textbox and button in the main window that I would like to access from the control... is this possible?

It would save me alot of time rather than changing the content of the entire window and displaying the same textbox/button in every usercontrol. If anyone has an example of this it would be much appreciated.

1
  • Took another look at this - have you tried accessing the parent elements with DataBinding and a RelativeSource of ancestor? Here is a good SO answer if so. If that doesn't seem more like a good solution you may want to post a bit of code to illustrate the problem. Cheers Commented Apr 18, 2012 at 22:59

3 Answers 3

3

Yes it is possible and here is some code I have used to compose presentations out of UserControls that have DPs.

I don't love it even a little, but it works. I also think this is a great topic and maybe some code will help get some better answers!

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> 

UserControl Code Behind

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

Another UserControl showing Composition

<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

Sign up to request clarification or add additional context in comments.

1 Comment

@KendallFrey. It isn't that simple when you think about it, but if it is to you just post some simple and clear code to make your case.
3

A better design pattern would be to have the usercontrol notify (via event) the main window when something needs to be changed, and to ask the window (via method) when it needs some information. You would, for example, have a GetText() method on the window that the usercontrol could call, and a ChangeText event on the usercontrol that the window would subscribe to.

The idea is to keep the window in control at all times. Using this mentality will make it easier for you to develop applications in the future.

2 Comments

So using your example if you had a textbox and button how would you send the text to the usercontrol and then populate that control with the text on button click?
Create a method on the usercontrol (say, SetText(string text)). In button1_Click, call myUserControl.SetText(myTextBox.Text). In the SetText method in the usercontrol, you can do whatever you want to populate data in the usercontrol.
2

To answer your question: yes, you can either access parent controls either through a RelativeSource binding or through the Parent member in the back code. But a better answer is similar to @KendallFrey answer. Adopt a framework like Light MVVM and use its messenger class or use events the way Kendall described.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.