Manipulation events not firing
Asked Answered
P

1

6

I'm new to developing in WPF for touchscreens, and I'm having trouble interpreting manipulation events. What I want to do is fairly simple I believe: when the user pinches anywhere on a UserControl, it will perform an action.

So, in the control I have (this is Surface 2.0 / Windows Touch):

XAML

<Grid Background="White" IsManipulationEnabled="True" 
ManipulationStarting="Grid_ManipulationStarting" 
ManipulationDelta="Grid_ManipulationDelta">
    <!--Some content controls-->
</Grid>

C#

private void Grid_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
{
    e.ManipulationContainer = this;
}

private void Grid_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
    //do the thing... you know, that thing you do
}

However, neither of these events fire when I rub my hands all over the screen. I think I must not understand the routing of the event in this situation. My monitor (3M MicroTouch PX) has not had any trouble understanding touch events or built-in manipulation like in ScatterViewItems.

EDIT: I removed controls from inside the Grid and they fire now, so I guess manipulations are being intercepted by the content. Sorry, should have been more clear about the contents of the control, because they're the problem it seems.

Specifically I think it has to do with the fact that I have a SurfaceListBox inside. I would imagine the SurfaceListBox is intercepting manipulation. Is there a way I can tell it to step off? I'm still trying to wrap my head around the way WPF does events.

Edit2: Going to paste some more complete code.

SEMANTICPANEL.XAML FULL

<UserControl x:Class="SemanticZoom.SemanticPanel"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:SemanticZoom"
         xmlns:views="clr-namespace:SemanticZoom.Views"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
</UserControl.Resources>
<Grid Background="White" IsManipulationEnabled="True" ManipulationStarting="Grid_ManipulationStarting" ManipulationDelta="Grid_ManipulationDelta">
    <views:CategoryView x:Name="CategoryView"/>
    <views:ShelfView x:Name="ShelfView" Visibility="Hidden" />
    <views:BookView x:Name="BookView" Visibility="Hidden" />
</Grid>

SEMANTICPANEL.CS FULL

public partial class SemanticPanel : UserControl
{
    public SemanticPanel()
    {
        InitializeComponent();
        CategoryView.CategorySelected += new EventHandler(CategoryView_CategorySelected);
        ShelfView.BookSelected += new EventHandler(ShelfView_BookSelected);
        ShelfView.ZoomOut += new EventHandler(View_ZoomOut);
    }

    void View_ZoomOut(object sender, EventArgs e)
    {
        if (sender == ShelfView)
        {
            ShelfView.Visibility = System.Windows.Visibility.Hidden;
            CategoryView.Visibility = System.Windows.Visibility.Visible;
        }
        else if (sender == BookView)
        {
            BookView.Visibility = System.Windows.Visibility.Hidden;
            ShelfView.Visibility = System.Windows.Visibility.Visible;
        }
    }

    void ShelfView_BookSelected(object sender, EventArgs e)
    {
        BookView.Books = ShelfView.BookList;
        ShelfView.Visibility = System.Windows.Visibility.Hidden;
        BookView.Visibility = System.Windows.Visibility.Visible;
    }

    void CategoryView_CategorySelected(object sender, EventArgs e)
    {
        ShelfView.Category = CategoryView.ActiveCategory;
        ShelfView.Visibility = System.Windows.Visibility.Visible;
        CategoryView.Visibility = System.Windows.Visibility.Hidden;
        ShelfView.RefreshBooks();
    }

    private void Grid_ManipulationStarting(object sender, ManipulationStartingEventArgs e)
    {
        //e.ManipulationContainer = this;
    }

    private void Grid_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
    {
        if (e.DeltaManipulation.Scale.X < 0)
        {
            if (ShelfView.Visibility == System.Windows.Visibility.Visible)
            {
                ShelfView.Visibility = System.Windows.Visibility.Hidden;
                CategoryView.Visibility = System.Windows.Visibility.Visible;
            }
            else if (BookView.Visibility == System.Windows.Visibility.Visible)
            {
                BookView.Visibility = System.Windows.Visibility.Hidden;
                ShelfView.Visibility = System.Windows.Visibility.Visible;
            }
        }
    }

CATEGORYVIEW.XAML

<UserControl x:Class="SemanticZoom.Views.CategoryView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:s="http://schemas.microsoft.com/surface/2008"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
    <!--CATEGORY TEMPLATE-->
    <DataTemplate x:Name="CategoryTemplate" x:Key="CategoryTemplate">
        <s:SurfaceButton Background="Gray" Click="CategoryClicked" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="200" Width="300">
            <TextBlock Text="{Binding Name}" TextWrapping="Wrap" Foreground="White" FontSize="20" FontWeight="Bold" />
        </s:SurfaceButton>
    </DataTemplate>
    <!--CATEGORY STYLE-->
    <Style TargetType="{x:Type s:SurfaceListBoxItem}">
        <Setter Property="Width" Value="300"/>
        <Setter Property="Height" Value="200"/>
    </Style>
</UserControl.Resources>
<Grid>
    <s:SurfaceListBox x:Name="CategoryList" ItemTemplate="{StaticResource CategoryTemplate}">
        <s:SurfaceListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel IsItemsHost="True"
                           Height="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType={x:Type ScrollContentPresenter}, Mode=FindAncestor}}"/>
            </ItemsPanelTemplate>
        </s:SurfaceListBox.ItemsPanel>
    </s:SurfaceListBox>
</Grid>

Just don't judge me because a) yes I'm trying to emulate Semantic Zoom and b) yes I'm doing a hacky job of it. I just need a simple working concept. Each of the views is basically similar to CategoryView.

Penicillium answered 9/4, 2012 at 20:56 Comment(5)
Why do you change e.ManipulationContainer ?Sophrosyne
Also are you sure you touch screen in area of our Grid? Is it big enough?Sophrosyne
@AndriyBuday: I don't really know, it was part of a sample I looked at. Doesn't make a difference since it's never called, but I'll comment it out until I work things out. The Grid is fullscreen right now, and the background color confirms that. So I'm not missing it, at least.Penicillium
I made some edits discussing what happens if I remove all of the grid's content. It seems that something inside is keeping the manipulation from coming back to the top. I'm just not sure how to keep it from doing that.Penicillium
If your list intercepts event you can try IsManipulationEnabled="False" for your SurfaceListBox if it is there.Sophrosyne
P
0

Thank you for your help Andriy, but it appears the problem was as simple as my monitor being far too insensitive. After I removed event hooks for all content on manipulation events, leaving only the hooks in the parent Grid, and then pressed VERY hard with two fingers on the screen, I got the events to fire. Probably need to mess a bit more with the routing, though.

Penicillium answered 10/4, 2012 at 19:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.