In my Windows-Runtime app, I have a theme with a style that has a Behavior
defined for the DoubleTapped action:
These are the XML Namespaces:
xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
And this is the style:
<Style x:Name="DisplayImage" TargetType="ScrollViewer">
<Setter Property="VerticalScrollBarVisibility" Value="Hidden" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="ZoomMode" Value="Disabled" />
<Setter Property="i:Interaction.Behaviors">
<Setter.Value>
<i:BehaviorCollection>
<core:EventTriggerBehavior EventName="DoubleTapped">
<local:ScrollViewerDoubleTap />
</core:EventTriggerBehavior>
</i:BehaviorCollection>
</Setter.Value>
</Setter>
</Style>
This is my Behavior
:
[DefaultEvent(typeof(ScrollViewer),"DoubleTapped")]
public class ScrollViewerDoubleTap : DependencyObject, IAction
{
public object Execute(object sender, object parameter)
{
ScrollViewer sv = (ScrollViewer)sender;
if (sv.HorizontalScrollBarVisibility == ScrollBarVisibility.Disabled)
{
sv.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
}
else
{
sv.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
}
return sender;
}
}
And this is how I am using it:
<ScrollViewer Style="{StaticResource Image}" MaxWidth="1067">
<Border BorderBrush="Black" BorderThickness="1">
<Image Source="MyImage.png"/>
</Border>
</ScrollViewer>
When I double-tap the first image on a page that has this style, it works perfectly; however, when I double-tap the other images on the page, the behavior code is never run. I know it is never run because I ran it with breakpoints, and it would break when I double-tapped the first image, but not the second. I will appreciate any tips on why this is happening.
We can do this using pure XAML
...and a reusable attached property, that receives a
DataTemplate
with aBehaviorCollection
(or a singleBehavior
).You don't have to change your code-behind.
Or if you need a few
Behaviors
at a time:The attached property
You don't even need to change it.
Why is it better?
It's a more flexible way to achieve this than Justin XL suggested.
His code requires modifying code-behind in order to re-use it. Each time when you want to re-use it, you will need to set the
EventName
(in this lineEventName = "DoubleTapped"
) and theBehavior
(this lineeventTriggerBehavior.Actions.Add(new ScrollViewerDoubleTap());
).This won't work because behaviors, actions or triggers are designed to be attached to a single element. When you define it inside a style's setter, it's like you are trying to associate it with multiple elements and as you have already seen, the trigger is only called when you interact with the first element with this style.
There's a simple way to fix this. Basically, you need to make sure each element that's associated with this style has a new instance of the trigger you have created. You can have all this logic wrapped inside an attached property and then your style will only need to reference this property.
This is how this attached property is implemented.