controltemplateloaded

Detecting when a template was loaded in wpf


I am working with an attached behavior for logging user actions on a ScrollBar.

my code:

class ScrollBarLogBehavior : Behavior<ScrollBar>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.Loaded += new RoutedEventHandler(AssociatedObject_Loaded);
    }

    void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
    {
        ...
        var track = (Track)AssociatedObject.Template.FindName("PART_Track", AssociatedObject);
        // ** HERE is the problem: track is null ! **
        ...
    }

How can I detect that the template has loaded and I can find the Track? (when I call AssociatedObject.Template.LoadContent() the result containt the requested Track, so it i a matter of timing and not a matter of wrong template or naming)


Solution

  • I did not find any good way to detect when the template was loaded. However, I did find a way to find the Track:

    1. in OnAttached() - register to Scroll event fo the ScrollBar (this can only happen after the entire template is loaded, of course):
        protected override void OnAttached()
        {
            base.OnAttached();
            _scrollHandler = new ScrollEventHandler(AssociatedObject_Scroll);
            AssociatedObject.AddHandler(ScrollBar.ScrollEvent, _scrollHandler, true);
        }
    
    1. When handling the Scroll event, remove registration and find the Thumb:
        void AssociatedObject_Scroll(object sender, ScrollEventArgs e)
        {
            var track = (Track)AssociatedObject.Template.FindName("PART_Track", Associated
            if (track == null)
                return;
            AssociatedObject.RemoveHandler(ScrollBar.ScrollEvent, _scrollHandler);
            // do my work with Track
            ...
        }