2

我正在使用附加行为来记录滚动条上的用户操作。

我的代码:

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 ! **
        ...
    }

如何检测到模板已加载并且可以找到 Track?(当我调用AssociatedObject.Template.LoadContent()结果包含请求的轨道时,这是时间问题,而不是错误的模板或命名问题)

4

3 回答 3

1

我没有找到任何检测模板何时加载的好方法。但是,我确实找到了找到 Track 的方法:

  1. 在 OnAttached() - 注册到 ScrollBar 的 Scroll 事件(当然,这只能在整个模板加载后发生):
    protected override void OnAttached()
    {
        base.OnAttached();
        _scrollHandler = new ScrollEventHandler(AssociatedObject_Scroll);
        AssociatedObject.AddHandler(ScrollBar.ScrollEvent, _scrollHandler, true);
    }
  1. 处理Scroll事件时,去掉注册,找到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
        ...
    }
于 2014-12-18T10:00:46.123 回答
0

覆盖方法 OnApplyTemplate

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        var textBox = Template.FindName("PART_Textbox", this) as TextBox;
    }
于 2014-12-17T14:44:48.677 回答
0

如果我理解正确,您希望创建一个附加行为,该行为将ScrollBar在加载后引用模板部分。

以下应该有效:

    internal static class ScrollBarLogBehavior
    {
        public static readonly DependencyProperty LogUserActionProperty = DependencyProperty.RegisterAttached(
            "LogUserAction",
            typeof(bool),
            typeof(ScrollBarLogBehavior),
            new UIPropertyMetadata(default(bool), LogUserActionChanged));

        public static bool GetLogUserAction(DependencyObject obj)
        {
            return (bool)obj.GetValue(LogUserActionProperty);
        }

        public static void SetLogUserAction(DependencyObject obj, bool value)
        {
            obj.SetValue(LogUserActionProperty, value);
        }

        public static void LogUserActionChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)
        {
            if (s is ScrollBar scrollBar)
            {
                scrollBar.Loaded += OnScrollBarLoaded;
            }
        }

        private static void OnScrollBarLoaded(object sender, RoutedEventArgs e)
        {
            if (sender is ScrollBar scrollBar)
            {
                if (scrollBar.Template != null)
                {
                    // I'm not sure, but the `name` in the following method call might be case sensitive.
                    if (scrollBar.Template.FindName("PART_Track", scrollBar) is Track track)
                    {
                        // do work with `track` here
                    }
                }
            }
        }
    }

您可以在其中“附加” XAML 中的行为:

<ScrollBar guiControls:ScrollBarLogBehavior.LogUserAction="True">
  <!-- more here -->
</ScrollBar>

请注意:此实现完全忽略了bool正在设置的值LogUserAction

于 2021-02-28T13:10:36.807 回答