tags:

views:

290

answers:

1

I'm getting some unexpected behavior in WPF. Here's my scenario:

  1. I have a UserControl on a Window. Let's call it "Surface". It has a Canvas on it.
  2. I have a second UserControl. Let's call it "PlayingCard".
  3. I have the PlayingCard UserControl added as a Child of the Surface's Canvas. Visually it displays just as it should, on top of the Surface.

This is all a setup for some drag-and-drop operations between "Surfaces" in a Window. I started by individually wiring up all the drag-and-drop events on the Surface class and everything worked fine. I could correctly detect the PlayingCard UserControl under the mouse and drag it, use Adorners for feedback, etc.

Then I went to abstract the drag-and-drop guts into a separate, static class. Suddenly, the UIElement detected under the mouse click is no longer the PlayingCard, but the Surface!

I currently have THREE different event handlers wired up to the Surface's PreviewLeftMouseButtonDown event, plus I'm overriding the OnPreviewLeftMouseButtonDown method on the Surface. I would expect consistent behavior between all of these ways to handle this method, but I am not getting it. Here's the results:

(1) I have an instantiated class called Test that has a method on it wired up to the Surface's PreviewLeftMouseButtonDown event. This happens in the Window's main method. It detects the Surface, not the PlayingCard, as the Source.

public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

           TestClass test = new TestClass();
           _leftSurface.PreviewMouseLeftButtonDown += test.Test_PreviewMouseLeftButtonDown;

(2) I have a static class called DragDropManager that is wired up to the Surface's event as well, also in the Window main method. It also detects the Surface as the source, not the PlayingCard.

public Window1()
        {
            InitializeComponent();

           TestClass test = new TestClass();
           _leftSurface.PreviewMouseLeftButtonDown += test.Test_PreviewMouseLeftButtonDown;

            _leftSurface.PreviewMouseMove += DragDropManager.PreviewMouseMove;

(3) I am overriding the Surface's OnPreviewLeftMouseButtonDown event. It detects the Surface as the source:

  protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnPreviewMouseLeftButtonDown(e);

(4) The Surface class has its own event handler, specified in the XML, and it CORRECTLY detects the PlayingCard as the source.

<UserControl x:Class="WpfTest.Surface"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">
    <Border Name="_border" BorderThickness="4" BorderBrush="Blue">
        <Canvas Name="_surface" Background="Black" AllowDrop="True"
                ClipToBounds="True"
                PreviewMouseMove="Surface_PreviewMouseMove"
                PreviewMouseLeftButtonDown="Surface_PreviewMouseLeftButtonDown"
                DragOver="Canvas_DragOver" DragLeave="Canvas_DragLeave">


        </Canvas>
    </Border>
</UserControl>

The only event handler that correctly detects the PlayingCard as the MouseButtonEventArgs.Source is the event handler that is assigned to the Surface through the XML.

Why do I get two different results for this? Why don't the other event handlers correctly report the PlayingCard as the source?

A: 

Try e.OriginalSource.

Donnelle
I have to do short answers or my work network times out instantly.
Donnelle
OriginalSource gives me the Canvas on the Surface. No help.
Chris Holmes