none
How do I make mouse events fire on Canvas?

    Question

  • Hi I have an application in which I want to catch the mouse events in a Canvas, the piece of XAML code for that is :

           <Viewbox Stretch="Uniform" Grid.Row="1">
                <Border Margin="5" BorderBrush="Black"
                        BorderThickness="1" Grid.Row="1"
                        HorizontalAlignment="Left">
                    <Canvas Name="canvas1" Width="365" Height="322.5"
                            ClipToBounds="True" 
                            MouseLeftButtonDown="OnMouseLeftButtonDown" 
                            MouseLeftButtonUp="OnMouseLeftButtonUp" 
                            MouseMove="OnMouseMove" />
                </Border>
            </Viewbox>

    When I run the application the events for the mouse do not triger. I have also test the canvas with the focusable property set to true, no luck what so ever.

    I want to draw different shapes on the canvas, and the posibilty to move them. If you have an other way to do it please let me know.

    thanks
    Saturday, May 09, 2009 6:33 PM

Answers

  • The canvas is over a Transparent Window ? Because if it is the case all the controls wich has transparent background don't receive focus.

    Thats is why, when you add the background everything is working.
    Saturday, May 09, 2009 7:12 PM
  • The canvas is over a Transparent Window ? Because if it is the case all the controls wich has transparent background don't receive focus.

    Thats is why, when you add the background everything is working.

    I agree with Mariano.

    The real 100% transparente Canvas will not fire mouse move events.
     
    Windows supports transparency at the HWND level through a feature called "layered windows". 
    Layered windows are represented by a bitmap. The Operation System(OS) renders the bitmap whenever it needs to. 
    For the OS need to respond very quickly to mouse movement, Windows uses a dedicated Raw Input Thread (RIT).
    RIT runs in the kernel and handles the singals from mouse hardware.
    RIT can scan over the HWND hierarchy to detect which window the mouse is over.
    For normal windows, the RIT checks the mouse position against the window's rectangle.
    For layered windows, the RIT looks in the bitmap that specifies the content for the window and checks the effective transparency at that location. The effective transparency can be affected by opacity, color and alpha channel.
    If the pixel is 100% transparent, the RIT skips the window and keeps looking.  This point is the reason that MouseMove event is not fired.
    If the Background of window and Canvas are both Transparent, all the pixels that represent this control(Canvas in your example) in the layered windows are totally transparent. As described above, RIT will skip them and never send WM_MOUSEMOVE message.

    So if you want only show up the control only when the mouse is over and otherwise and the window is transparent, you have to make the control not 100% transparent. For example adding a background color to the Canvas.

    • Proposed as answer by Tao Liang Monday, May 11, 2009 7:03 AM
    • Marked as answer by Tao Liang Thursday, May 14, 2009 5:26 AM
    Monday, May 11, 2009 7:03 AM

All replies

  • It Seems that if I Add a backgroud color to the canvas the mouse events works.
    Saturday, May 09, 2009 7:03 PM
  • The canvas is over a Transparent Window ? Because if it is the case all the controls wich has transparent background don't receive focus.

    Thats is why, when you add the background everything is working.
    Saturday, May 09, 2009 7:12 PM
  • The canvas is over a Transparent Window ? Because if it is the case all the controls wich has transparent background don't receive focus.

    Thats is why, when you add the background everything is working.

    I agree with Mariano.

    The real 100% transparente Canvas will not fire mouse move events.
     
    Windows supports transparency at the HWND level through a feature called "layered windows". 
    Layered windows are represented by a bitmap. The Operation System(OS) renders the bitmap whenever it needs to. 
    For the OS need to respond very quickly to mouse movement, Windows uses a dedicated Raw Input Thread (RIT).
    RIT runs in the kernel and handles the singals from mouse hardware.
    RIT can scan over the HWND hierarchy to detect which window the mouse is over.
    For normal windows, the RIT checks the mouse position against the window's rectangle.
    For layered windows, the RIT looks in the bitmap that specifies the content for the window and checks the effective transparency at that location. The effective transparency can be affected by opacity, color and alpha channel.
    If the pixel is 100% transparent, the RIT skips the window and keeps looking.  This point is the reason that MouseMove event is not fired.
    If the Background of window and Canvas are both Transparent, all the pixels that represent this control(Canvas in your example) in the layered windows are totally transparent. As described above, RIT will skip them and never send WM_MOUSEMOVE message.

    So if you want only show up the control only when the mouse is over and otherwise and the window is transparent, you have to make the control not 100% transparent. For example adding a background color to the Canvas.

    • Proposed as answer by Tao Liang Monday, May 11, 2009 7:03 AM
    • Marked as answer by Tao Liang Thursday, May 14, 2009 5:26 AM
    Monday, May 11, 2009 7:03 AM
  • There is also a difference between having no color set and setting it to Colors.Transparent. So it might work if you explicitly set Background="Transparent".

    hth,
    Marcel
    Tuesday, May 12, 2009 7:31 AM