user2509848
user2509848

Reputation:

Behaviors in Windows-Runtime app

I have a set of ScrollViewers in my Windows Store app that need to always have an action occur when they are double-tapped (namely, expand to full size). They are in different files, or I would probably just put this in the code-behind for that file:

private void ScrollViewer_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
    ScrollViewer sv = (ScrollViewer)sender;
    if (sv.HorizontalScrollBarVisibility == ScrollBarVisibility.Disabled)
    {
        sv.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
    }
    else
    {
        sv.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
    }
}

I was told to look into Behaviors, so I researched behaviors, and with the help of a couple online tutorials, I was able to come up with this:

class ViewboxDoubleTap : DependencyObject, IBehavior
{
    public interface IBehavior
    {
        DependencyObject AssociatedObject { get; }
        void Attach(DependencyObject associatedObject);
        void Detach();
    }

    public void Attach(DependencyObject associatedObject)
    {
        if ((associatedObject != AssociatedObject) && !DesignMode.DesignModeEnabled)
        {
            if (AssociatedObject != null)
                throw new InvalidOperationException("Cannot attach behavior multiple times.");

            AssociatedObject = associatedObject;
            var fe = AssociatedObject as FrameworkElement;
            if (fe != null)
            {
                fe.AddHandler(UIElement.DoubleTappedEvent, new DoubleTappedEventHandler(ScrollViewer_DoubleTapped), true);
            }
        }
    }

    public void Detach()
    {
        var fe = AssociatedObject as FrameworkElement;
        if (fe != null)
        {
            fe.RemoveHandler(UIElement.DoubleTappedEvent, new DoubleTappedEventHandler(ScrollViewer_DoubleTapped));
        }

        AssociatedObject = null;
    }

    public DependencyObject AssociatedObject { get; private set; }

    private void ScrollViewer_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
    {
        ScrollViewer sv = (ScrollViewer)sender;
        if (sv.HorizontalScrollBarVisibility == ScrollBarVisibility.Disabled)
        {
            sv.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
        }
        else
        {
            sv.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
        }
    }
}

Now, everything is compiling nicely, but I can't get this attached to the XAML:

XML Namespaces:

xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:local="using:MyApp.Folder"
xmlns:global="using:MyApp"

Relevant code:

<ScrollViewer HorizontalAlignment="Left" VerticalScrollBarVisibility="Hidden" MaxZoomFactor="2" MinZoomFactor="1" MaxWidth="1067">

    <i:Interaction.Behaviors>
        <core:EventTriggerBehavior EventName="DoubleTapped">
            <global:ViewboxDoubleTap />
        </core:EventTriggerBehavior>
    </i:Interaction.Behaviors>

    <Border BorderBrush="Black" BorderThickness="1">
        <Image Source="MyImage.png"/>
    </Border>
</ScrollViewer>

When I try to go to this page, nothing happens, and when I debug, it gives me this error message:

WinRT information: Cannot add instance of type 'LearnOneNote.ViewboxDoubleTap' to a collection of type 'Microsoft.Xaml.Interactivity.ActionCollection'. [Line: 25 Position: 30]

Additionally, it is telling me that ViewboxDoubleTap is not in namespace MyApp, but when I type <global:, it pulls it up itself; I don't know if this is important to the problem.

Any help will be appreciated.

Upvotes: 3

Views: 194

Answers (1)

user2509848
user2509848

Reputation:

After being tipped to check out IAction (thank you, franssu), I came up with this:

[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;
    }
}

This works perfectly.

Upvotes: 2

Related Questions