I have four buttons and four text boxes where each button is linked to one of the textblocks. When the mouse is over the button I want the corresponding textblock to fade in (and out on mouse leave). There are plenty of examples of this showing a single button and textblock where you can simply bind a datatrigger to the button name in the textblock style.
Here's what I've got so far (all of this is in a textblock style):
<DataTrigger Binding="{Binding ElementName=UpdateButton, Path=IsMouseOver}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard TargetProperty ="Opacity" Duration="00:00:01">
<DoubleAnimation From="0" To="1" Duration="00:00:01"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard TargetProperty ="Opacity" Duration="00:00:01">
<DoubleAnimation From="1" To="0" Duration="00:00:01"/>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
As of right now, when I mouse over the Update Button, all of the textblocks show instead of just the one associated with the Update Button.
To fix this I could create styles for each textblock by their name and bind to the appropriate button, but this is a huge amount of repetition. I could likely used "BasedOn" to separate the button binding, but then we're still duplicating all of the code for the Storyboards and whatnot. But does anyone know a better way?
It would seem like there should be a way create this all in a single style using a single generic binding but link the specific buttons to their textblocks, so the button only triggers the Storyboard for it's linked textblock. Anyone know how to do this, or a better way?
A good way to handle this is to create a custom inherited TextBlock
that can store reference to a button.
Example
using System.Windows;
using System.Windows.Controls;
//Custom TextBlock
public class SpecialTextBlock : TextBlock
{
//This will be the button reference
public Button BoundButton { get; set; }
//Register the BoundButton as a dependency to allow binding
public static readonly DependencyProperty ButtonProperty = DependencyProperty.Register
(
"BoundButton",
typeof(Button),
typeof(SpecialTextBlock),
new FrameworkPropertyMetadata(default(Button))
);
}
Now that your new SpecialTextBlock
is set up, you can create a new style for it. Use your original style, but apply it to TargetType="local:SpecialTextBlock"
instead of TargetType="TextBlock"
.
Then update your DataTrigger from your example within the style so that the trigger binds to itself (the SpecialTextBlock
), and then looks at the referenced Button
path.
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=BoundButton.IsMouseOver}" Value="True">
...
Now you are set up and can create your TextBlocks
like so without having to restyle.
//Set your BoundButton binding to specify which button triggers the animation.
<local:SpecialTextBlock BoundButton="{Binding ElementName=UpdateButton}" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With