Search code examples
c#wpfroutedevent

WPF RoutedEventHandler doesnt work with content


I have problem with c# WPF routedevent. This code works fine:

        MyLabel myLabel = new MyLabel();//MyOwn component
        myLabel.Oma += new RoutedEventHandler(myLabel_Click);
        GameArea.Children.Add(mylabel);//GameArea is UniformGrid

But when I put myLabel in ToggleButton's content, routedeventhandler(myLabel_Click) doesnt catch the Oma-event(I debugged that):

        MyLabel myLabel = new MyLabel();//MyOwn component
        myLabel.Oma += new RoutedEventHandler(myLabel_Click);
        System.Windows.Controls.Primitives.ToggleButton box = new System.Windows.Controls.Primitives.ToggleButton();
        box.Content = myLabel;
        GameArea.Children.Add(box);//GameArea is UniformGrid

So why do ToggleButton blocks my routedevent?

EDIT: Code works fine, but it makes troubles, when I put myLabel in ToggleButton's content.
OmaEvent in MyLabel seems like this:

public static readonly RoutedEvent OmaEvent =
EventManager.RegisterRoutedEvent("Oma", RoutingStrategy.Bubble,
typeof(RoutedEventHandler), typeof(MyLabel));

    public event RoutedEventHandler Oma
    {
        add { AddHandler(OmaEvent, value); }
        remove { RemoveHandler(OmaEvent, value); }
    }

    protected override void OnMouseDown(MouseButtonEventArgs e)
    {
        base.OnMouseDown(e);
        CaptureMouse();
    }

    protected override void OnMouseUp(MouseButtonEventArgs e)
    {
        base.OnMouseUp(e);
        if (IsMouseCaptured)
        {
            ReleaseMouseCapture();
            if (IsMouseOver)
                RaiseEvent(new RoutedEventArgs(OmaEvent, this));
        }

    }

OmaEvent never raise, if I put it inside the ToggleButton. If I don't put it inside the ToggleButton, it works.


Solution

  • The Oma event is not being raised because the parent ToggleButton steals the mouse capture in its ButtonBase.OnMouseLeftButtonDown method, which gets invoked after your OnMouseDown method. No other element will receive mouse events as long as the ToggleButton has mouse capture, so your label will not receive the MouseUp event, and your OnMouseUp method will not be called.

    Set e.Handled = true; in your OnMouseDown method to prevent the event from bubbling up to the ToggleButton. This will prevent it from stealing focus, though it will also prevent the button from working normally when the MyLabel within is clicked. It's unclear what behavior you want in this scenario.