none
Bubbled Event from User Control Library Not Firing RRS feed

  • Question

  • Hey All...

    I've been reviewing threads in various places trying to deal with a scenario that I think should be relatively easy to handle.

    My main code has a HandleAction method. An ActionToolbar (from a User Control Library) is dynamically added to the main Window. When the user clicks a button on the ActionToolbar, it should bubble up and fire my NavigatePage method.

    In the ActionToolbar, I've added:

        Public Shared ReadOnly ActionEvent As RoutedEvent = EventManager.RegisterRoutedEvent("CustomClick", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(navPane))


    Me.Button1.AddHandler(Button.ClickEvent, New RoutedEventHandler(AddressOf Button1_Click))

    And within the control itself, the event is firing as expected.

    However, in the Main window, I do a

            pnlNav.AddHandler(pnlNav.ActionEvent, New RoutedEventHandler(AddressOf HandleAction), True)

    (where pnlNav is my toolbar object)

    Unfortunately, the HandleAction method is never called.

    All of the samples I've seen always refer to the routing occurring within an existing control, not being shared with an outside library.

    This is possible - isn't it?

    If not, what would you suggest?

    Thanks


    Andrew MacNeill (MVP VFP)
    Wednesday, June 2, 2010 1:23 PM

Answers

  • Hi Andrew,

    You need to define the event in the UserControl as an attached event, so that this event can bubble outside the UserControl. For more information on attached event in WPF, please read the following MSDN document:

    "Attached Events Overview"
    http://msdn.microsoft.com/en-us/library/bb613550.aspx

    Please try my suggestion to see if it works.

    Sincerely,
    Linda Liu

    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • Marked as answer by Linda Liu Wednesday, June 9, 2010 2:36 AM
    Thursday, June 3, 2010 8:34 AM
  • Hi Andrew,

    Thank you for your reply!

    The difference of routed event and attached event implementation pattern is that Add*Handler and Remove*Handler are needed in the class that defines the attached event. The following is a sample.

    Class AquariumFilter

    Public Shared ReadOnly NeedsCleaningEvent As RoutedEvent = EventManager.RegisterRoutedEvent("NeedsCleaning", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(AquariumFilter))
    Public Shared Sub AddNeedsCleaningHandler(ByVal d As DependencyObject, ByVal handler As RoutedEventHandler)
        Dim uie As UIElement = TryCast(d, UIElement)
        If uie IsNot Nothing Then
            uie.AddHandler(AquariumFilter.NeedsCleaningEvent, handler)
        End If
    End Sub
    Public Shared Sub RemoveNeedsCleaningHandler(ByVal d As DependencyObject, ByVal handler As RoutedEventHandler)
        Dim uie As UIElement = TryCast(d, UIElement)
        If uie IsNot Nothing Then
            uie.RemoveHandler(AquariumFilter.NeedsCleaningEvent, handler)
        End If
    End Sub

    End Class

    Please try my suggestion to see if there's any question.

    Sincerely,
    Linda Liu


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • Marked as answer by Linda Liu Wednesday, June 9, 2010 2:35 AM
    Tuesday, June 8, 2010 8:08 AM
  • Linda,

     

    I found the problem - it was in this area of code:

     RaiseEvent(ByVal sender As Object, ByVal e As RoutedEventArgs)

                Me.RaiseEvent(e)

            End RaiseEvent

     

    In short, it appears you can't simply call Me.RaiseEvent with the passed event args. You have to create your own.

    When I changed the code to:

                Dim newEventArgs As New RoutedEventArgs(navPane.NavigateEvent)

                Me.RaiseEvent(newEventArgs)

    It worked perfectly. I didn't even need the extra AddxxHandler stuff.




    Andrew MacNeill (MVP VFP)
    • Marked as answer by Linda Liu Wednesday, June 9, 2010 2:35 AM
    Tuesday, June 8, 2010 5:07 PM

All replies

  • Hi Andrew,

    You need to define the event in the UserControl as an attached event, so that this event can bubble outside the UserControl. For more information on attached event in WPF, please read the following MSDN document:

    "Attached Events Overview"
    http://msdn.microsoft.com/en-us/library/bb613550.aspx

    Please try my suggestion to see if it works.

    Sincerely,
    Linda Liu

    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • Marked as answer by Linda Liu Wednesday, June 9, 2010 2:36 AM
    Thursday, June 3, 2010 8:34 AM
  • Hi Andrew,

    How about the problem now?

    If the problem is still not solved, please feel free to let me know.

    Sincerely,
    Linda Liu


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    Monday, June 7, 2010 6:17 AM
  • Hi Linda,

    I believe  I have already done this. My HandleEvent method is defined as:

     

    Public Shared ReadOnly NavigateEvent As RoutedEvent = EventManager.RegisterRoutedEvent("CustomClick", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(navPane))

    .....

        Public Custom Event CustomClick As RoutedEventHandler

            AddHandler(ByVal value As RoutedEventHandler)

                Me.AddHandler(NavigateEvent, value)

            End AddHandler

     

            RemoveHandler(ByVal value As RoutedEventHandler)

                Me.RemoveHandler(NavigateEvent, value)

            End RemoveHandler

     

            RaiseEvent(ByVal sender As Object, ByVal e As RoutedEventArgs)

                Me.RaiseEvent(e)

            End RaiseEvent

        End Event



    If I put msgbox code into these events, I can see they are being fired - but they are not being bubbled up to the main page's method.

    What am I missing?

    Thanks


    Andrew MacNeill (MVP VFP)
    Monday, June 7, 2010 10:33 AM
  • Hi Andrew,

    Thank you for your reply!

    The difference of routed event and attached event implementation pattern is that Add*Handler and Remove*Handler are needed in the class that defines the attached event. The following is a sample.

    Class AquariumFilter

    Public Shared ReadOnly NeedsCleaningEvent As RoutedEvent = EventManager.RegisterRoutedEvent("NeedsCleaning", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(AquariumFilter))
    Public Shared Sub AddNeedsCleaningHandler(ByVal d As DependencyObject, ByVal handler As RoutedEventHandler)
        Dim uie As UIElement = TryCast(d, UIElement)
        If uie IsNot Nothing Then
            uie.AddHandler(AquariumFilter.NeedsCleaningEvent, handler)
        End If
    End Sub
    Public Shared Sub RemoveNeedsCleaningHandler(ByVal d As DependencyObject, ByVal handler As RoutedEventHandler)
        Dim uie As UIElement = TryCast(d, UIElement)
        If uie IsNot Nothing Then
            uie.RemoveHandler(AquariumFilter.NeedsCleaningEvent, handler)
        End If
    End Sub

    End Class

    Please try my suggestion to see if there's any question.

    Sincerely,
    Linda Liu


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework! If you have any feedback, please tell us.
    • Marked as answer by Linda Liu Wednesday, June 9, 2010 2:35 AM
    Tuesday, June 8, 2010 8:08 AM
  • Thanks - I'll try that shortly.
    Andrew MacNeill (MVP VFP)
    Tuesday, June 8, 2010 11:47 AM
  • That still didn't work. So maybe the problem is on the "calling" part of it.

    From your revised example, I have:

    Class navPane

        Public Shared ReadOnly NavigateEvent As  _

            RoutedEvent = EventManager.RegisterRoutedEvent("CustomClick", RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(navPane))

        Public Sub New()

            InitializeComponent()

            Me.Button1.AddHandler(Button.ClickEvent, New RoutedEventHandler(AddressOf Button1_Click))       

        End Sub

        Public Shared Sub AddNavigateHandler(ByVal d As DependencyObject, ByVal handler As RoutedEventHandler)

            Dim uie As UIElement = TryCast(d, UIElement)

            If uie IsNot Nothing Then

                uie.AddHandler(navPane.NavigateEvent, handler)

            End If

        End Sub

        Public Shared Sub RemoveNavigateHandler(ByVal d As DependencyObject, ByVal handler As RoutedEventHandler)

            Dim uie As UIElement = TryCast(d, UIElement)

            If uie IsNot Nothing Then

                uie.RemoveHandler(navPane.NavigateEvent, handler)

            End If

        End Sub

     

     

        Public Custom Event CustomClick As RoutedEventHandler

            AddHandler(ByVal value As RoutedEventHandler)

                Me.AddHandler(NavigateEvent, value)

            End AddHandler

     

            RemoveHandler(ByVal value As RoutedEventHandler)

                Me.RemoveHandler(NavigateEvent, value)

            End RemoveHandler

     

            RaiseEvent(ByVal sender As Object, ByVal e As RoutedEventArgs)

                Me.RaiseEvent(e)

            End RaiseEvent

        End Event

     

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)

            RaiseEvent CustomClick(sender, e)

        End Sub

    End Class


    Now, in my calling application, I have:
    Class MainWindow

    Public Sub LoadSession(.....)

    pnlNav = New Library.pnlNav
            pnlNav.AddHandler(pnlNav.NavigateEvent, New RoutedEventHandler(AddressOf GotoPage), True)

    StackPanel.Children.Add(pnlNav)



    End Sub


        Private Sub GotoPage(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
            Window1.txbTitle.Text = "Navigating"
        End Sub

    End Class

    I'm sure I'm missing something very basic here - but I thought I had followed the previous examples to a T.

    Thanks for your help on this.


    Andrew MacNeill (MVP VFP)
    Tuesday, June 8, 2010 12:26 PM
  • I noticed that in one sample, they were manually adding the event into the XML so I tried that as well:

     

    <Grid xx:navPane.Navigate="GotoPage">

    But the event still didn't fire.

    If I put code into the NavigateEvent itself, it will fire - but that is at the user control level, not the higher level.

     


    Andrew MacNeill (MVP VFP)
    Tuesday, June 8, 2010 3:14 PM
  • Linda,

     

    I found the problem - it was in this area of code:

     RaiseEvent(ByVal sender As Object, ByVal e As RoutedEventArgs)

                Me.RaiseEvent(e)

            End RaiseEvent

     

    In short, it appears you can't simply call Me.RaiseEvent with the passed event args. You have to create your own.

    When I changed the code to:

                Dim newEventArgs As New RoutedEventArgs(navPane.NavigateEvent)

                Me.RaiseEvent(newEventArgs)

    It worked perfectly. I didn't even need the extra AddxxHandler stuff.




    Andrew MacNeill (MVP VFP)
    • Marked as answer by Linda Liu Wednesday, June 9, 2010 2:35 AM
    Tuesday, June 8, 2010 5:07 PM