Ask a questionAsk a question
 

QuestionEventTrigger not firing on custom Routed Event

  • Thursday, August 16, 2007 5:03 PMjturpin Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

     

    I believe this should be easy, but I have not had any luck so far. Hopefully I am missing something simple...

     

    Basically I have a ListBox contained in a UserControl (which is acutally in a separate assembly than the main app, but I don't think that matters).

     

    The DataTemplate for the ListBoxItem is defined in a resource dictionary (of the Main App - not the UserControl - but again I don't think that matters). I would like to have some EventTriggers in the DataTemplate trigger on custom Routed Events fired by the ListBox UserControl. Sounds straight forward, but it ain't working.

     

    I have verified that I am getting the events on the MainWindow (the parent of the UserControl) - both by subscribing to the events in XAML and in code. I have also verified that I am getting the events in the ListBoxItem (by subscribing in code) - if I use a custom ListBoxItem class inherited from ContenPresenter. However what is not working is the typical EventTrigger method in XAML. This is what my XAML for the DataTemplate looks like:

     

    Code Snippet

    <ResourceDictionary
      ....
      xmlns:uc="clr-namespace:UserControlListBox;assembly=UserControlListBox"
    >

    <DataTemplate x:Key="MenuItemTemplate">
        <DataTemplate.Resources>
            <... bunch of storyboards here ...>
        </DataTemplate.Resources>
        <Grid>
            <Grid x:Name="SelectedItemGrid">
              <... bunch of stuff defining selected state data presentation...>
            </Grid>
            <Grid x:Name="UnselectedItemGrid">
              <... bunch of stuff defining unselected state data presentation...>
            </Grid>
        </Grid>
        <DataTemplate.Triggers>
          <EventTrigger RoutedEvent="uc:MyListBox.PreviewUnselectItem">
            <BeginStoryboard Storyboard="{StaticResource DoUnselectItemAnimation}"/>
          </EventTrigger>
          <EventTrigger RoutedEvent="uc:MyListBox.PreviewSelectItem">
            <BeginStoryboard Storyboard="{StaticResource DoSelectItemAnimation}"/>
          </EventTrigger>
        </DataTemplate.Triggers>

    </DataTemplate>

    </ResourceDictionary>

     

     

     

     

    And in the UserControl containing the ListBox:

     

    Code Snippet

    public static readonly RoutedEvent PreviewUnselectItemEvent = EventManager.RegisterRoutedEvent(
    "PreviewUnselectItem", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(UCListBox));

     

    public event RoutedEventHandler PreviewUnselectItem
    {
     add { AddHandler(PreviewUnselectItemEvent, value); }
     remove { RemoveHandler(PreviewUnselectItemEvent, value); }
    }

     

    public static readonly RoutedEvent PreviewSelectItemEvent = EventManager.RegisterRoutedEvent(
    "PreviewSelectItem", RoutingStrategy.Tunnel, typeof(RoutedEventHandler), typeof(UCListBox));

     

    public event RoutedEventHandler PreviewSelectItem
    {
     add { AddHandler(PreviewSelectItemEvent, value); }
     remove { RemoveHandler(PreviewSelectItemEvent, value); }
    }

     

     

    // trigger the events...


    private void UnselectItemOccurs()
    {
       RaiseEvent(new RoutedEventArgs(PreviewUnselectItemEvent));
    }

    private void SelectItemOccurs()
    {
       RaiseEvent(new RoutedEventArgs(PreviewSelectItemEvent));
    }

     

     

     

    So just to verify... it is the Tunnel Event that I should trigger on as the Source of the Event is the ListBox and the consumer is a child of the ListBox - the ListBoxItem - or the DataTemplate applied to the ListBoxItem - correct?

     

    Why is this not working? Any help is much appreciated...

     

    p.s. I have no explanation why the CodeSnippets are showing up in Arial and not Courier... the show up in Courier while in design view but as soon as I post or preview they switch back to Arial.. weird...

All Replies

  • Thursday, August 16, 2007 10:38 PMjturpin Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Ok, still working on this... interestingly, there is another thread here with a similar problem...

     

    Some possible causes which have been ruled out include:

    • Nothing is consuming the event (marking it as handled) before it is getting to the desired target element (it is a custom routed event - i have removed all handlers - except for the EventTriggers in the DataTemplate)
    • I have verified that the event is indeed firing by adding ClassHandlers to the Window (root) and ListBoxItems (children) of the Source of the event.

    One side note: I am applying the DataTemplate to the ListBox in code and not XAML - through a DepencyProperty of my UserControl. Though I can't see how this would effect the firing of EventTriggers defined in the DataTemplate.

     

  • Monday, August 27, 2007 8:52 PMBen Carter - MSFT Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    If this is your tree (not exact):

    UserControl

        ListBox

            ListBoxItem

                DataTemplate Content

            ListBoxItem

                DataTemplate Content

            ...

     

    And you raise your event on the ListBoxItem, then the event will route as follows:

    UserControl -> ListBox -> ListBoxItem

    This means that the event will not hit the data template content, which contains the trigger.

     

    Perhaps you thought that tunnel was a broadcast, which WPF does not have. Bubble and Tunnel events have the same route. They just happen in different directions. If this is the case, you will need to figure out how to get the route to occur deeper in the tree. You could search your ListBoxItem for a ContentPresenter and fire the event there. That would likely be enough.

     

    Ben