简体   繁体   中英

Draw rectangle in a Canvas that resides in a ScrollViewer using mouse and touch

I got a Canvas inside ScrollViewer.

<ScrollViewer x:Name="svWorkSpace" Visibility="Collapsed" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
                      Tapped="svWorkSpace_Tapped"
                      PointerPressed="svWorkSpace_PointerPressed"
                      PointerMoved="svWorkSpace_PointerMoved"
                      PointerReleased="svWorkSpace_PointerReleased">
            <Grid>
                <Image x:Name="cvWorkImage"/>
                <Canvas x:Name="cvWorkSpace"/>
            </Grid>
        </ScrollViewer>

In PointerPressed code, I capture the starting point and in PointerMoved code, I draw a rectangle as pointer moves (also remove trailing rectangle a I move, maintaining only a single rectangle in the canvas. I achieve rectangle sizing effect using this method). PointerReleased will accept the last rectangle.

Everything works fine using a mouse in touch enabled device but not using finger. The image just scroll when I move my finger.

Tried to move the code into Canvas, like below. Failed to draw rectangle using both mouse and touch.

<ScrollViewer x:Name="svWorkSpace" Visibility="Collapsed" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
            <Grid>
                <Image x:Name="cvWorkImage"/>
                <Canvas x:Name="cvWorkSpace"
                      Tapped="svWorkSpace_Tapped"
                      PointerPressed="svWorkSpace_PointerPressed"
                      PointerMoved="svWorkSpace_PointerMoved"
                      PointerReleased="svWorkSpace_PointerReleased"/>

            </Grid>
        </ScrollViewer>

Point me in the right direction pls.

When the ScrollViewer receives the touch based PointerPressed it turns to Direct Manipulation to responsively handle panning and zooming. Direct Manipulation captures the pointer input so the Canvas' PointerMoved and PointerReleased events don't fire. No events -> no drawing.

The ScrollViewer pan or zoom with the mouse, so mouse events make it through to the Canvas.

Assuming you always want the Canvas to handle the pointer events rather than scrolling (perhaps there are other controls in the Grid that make use of the ScrollViewer), you can set the Canvas' ManipulationMone to all to let touches on the Canvas block touches on the ScrollViewer

<Canvas x:Name="cvWorkSpace"
    Background={ThemeResource WorkSpaceBackgroundBrush}
    Tapped="svWorkSpace_Tapped"
    ManipulationMode="All"
    PointerPressed="svWorkSpace_PointerPressed"
    PointerMoved="svWorkSpace_PointerMoved"
    PointerReleased="svWorkSpace_PointerReleased"/>

If you only sometimes want the Canvas to handle the pointer events then you can switch the ManipulationMode back to System to let the ScrollViewer handle it. If you want to draw on the Canvas with single-touch and pan/zoom with multi-touch then you can handle Manipulation events on the Canvas to pan and zoom.

Also make sure the Canvas isn't transparent and lets the pointer events pass through to whatever is behind it. If you want to draw on top of an image you can set an ImageBrush with the image as the Canvas' background rather than using a separate Image control.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM