2
votes

I have a UserControl contained within a parent window in WPF. The usercontrol contains a button that when pressed, needs to call back to the parent window and start a storyboard animation to set the opacity of the UserControl to 0, while setting the opacity of a different UserControl to 1.

So effectively there is a button within my usercontrol that hides the containing usercontrol and switches to another one being visible.

If the button is in the main window, it is easy as the first user control has an x:Name of leftpanel and the second is called leftpanelexpanded.

<DoubleAnimation Storyboard.TargetName="Leftpanel" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2" To="0"/>
<DoubleAnimation Storyboard.TargetName="Leftpanelexpanded" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2" To="1"/>

But with the button in the user control, I can't figure out how to have this animation target the "leftpanel" and "leftpanelexpanded" usercontrol objects. I have tried RelativeSource but I can only get a handle to the parent window this way, I cant get a handle to the user control contained within the parent window.

How can I do this?

1

1 Answers

0
votes

Well multiple ways you can address this:

  1. Have a custom Dependency Property in the UserControl that is say of type bool. On your Button click inside the UserControl set this bool DP to true. In the parent Window, use a `Trigger to check this DP and when True use a BeginStoryboard action to start the Storyboard.

  2. Repeat same process as above but use the Tag property instead of a custom DP. (Try to avoid this method. Just ain't too nice)

  3. Create a custom RoutedEvent in your UserControl and fire the event from the Button.Click. Have the parent Window subscribe to this event and invoke the Storyboard.

  4. If your using something like a Messenger / EventAggregator class, just send a message across to the parent View from the Button.Click and invoke the Storyboard from the parent View when receiving this message.

  5. Create an ICommand property in your parent-view and have your Button in the UserControl bind to this Command via a RelativeSource binding or if it's DataContext is the parent Window, you wouldn't even need a RelativeSource to access the command. In the Command's OnExecute(...) start the Storyboard.

Summary:

I bet there are quite a few more options I can't think of quickly, crux is when your Button.Click occurs inform the parent in your manner of choosing that it needs to change the state of it's children however it chooses to do so and give the responsibility of actioning that request to the parent View.

The child stops at the point of requesting a state change, the parent View is the one that actually does it. This saves you all the access to control's problem and also helps stay true to the principle of "Have one thing worry about that thing and that thing only"(the "thing" being each view's class here)