2

ScrollBar でのユーザー アクションをログに記録するための動作を添付して作業しています。

私のコード:

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

テンプレートが読み込まれたことを検出し、トラックを見つけるにはどうすればよいですか? (要求されたトラックを含む結果を呼び出すとAssociatedObject.Template.LoadContent()、タイミングの問題であり、間違ったテンプレートや名前の問題ではありません)

4

3 に答える 3

1

テンプレートがいつ読み込まれたかを検出する良い方法が見つかりませんでした。ただし、トラックを見つける方法を見つけました。

  1. In 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

私の理解が正しければ、ロード後にテンプレート パーツを参照する添付ビヘイビアを作成したいと考えて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 に答える