2


1

Silverlight TreeView ScrollViewerの問題

こんにちは、SilverlightのTreeViewコントロールについて質問がありました。

ツリービューに要素を動的に追加するアプリケーションがあります。 一部の要素は、水平スクロールが必要な長さです。 それらがツリービューに追加されると、ツリービューは正しく左にスクロールされたままなので、アイテムの終わりを見るにはスクロールする必要があります。 ただし、アイテムの1つ(ツリービューを非表示にする)をクリックし、実装した「結果に戻る」ボタンを使用すると(これは可視性の変更のみを処理することに注意してください)ツリービューが表示され、自動的にスクロールされますセンター。

結果に戻ったときにツリービューを左にスクロールする方法を知っている人はいますか?

ツリービューテンプレートをいじってみました:

                                                        True

しかし、それに関する問題は、背後のコードからScrollViewerにアクセスする方法がわからないことです…​ そのため、ScrollView.setScrollOffset(0d、0d)などを呼び出すことはできません。

何か案は? 感謝万円。

最後に、ツリービューを拡張する新しいコントロールの実装を避けたいと思います。 私は、C#コードビハインドからコントロールテンプレートに関連付けられた関数にアクセス/変更して使用する方法があることを本当に望んでいます。

2 Answer


0


これに添付プロパティを設定し、そこに必要なロジックを作成します。 次に、添付プロパティでツリービューを飾ります。 scrollviewerを含む他のコントロールと同様のことを行います。

public class ScrollResetService
{
    public static DependencyProperty IsScrollResetProperty = DependencyProperty.RegisterAttached("IsScrollReset",
                                                                                                 typeof(bool),
                                                                                                 typeof(ScrollResetService),
                                                                                                 new PropertyMetadata(false,
                                                                                                      OnIsScrollResetChanged));
    public static void SetIsScrollReset(DependencyObject d, bool value)
    {
        d.SetValue(IsScrollResetProperty, value);
    }

    public static bool GetIsScrollReset(DependencyObject d)
    {
        return d.GetValue(IsScrollResetProperty) == null ? false : (bool)d.GetValue(IsScrollResetProperty);
    }

    private static void OnIsScrollResetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var treeView = d as TreeView;
        bool isScrollReset;
        if (e.NewValue!= null && bool.TryParse(e.NewValue.ToString(), out isScrollReset) && treeView != null)
        {

            treeView.SelectedItemChanged += (sender, args) =>
                                               {
                                                   var scrolls =
                                                       treeView.GetAllLogicalChildrenOfType();
                                                   scrolls.ForEach(i => i.SetVerticalOffset(0));
                                               };

        }
    }

}

public static class Extensions
    {

public static IEnumerable GetAllLogicalChildrenOfType(this FrameworkElement parent)
        {
            Debug.Assert(parent != null, "The parent cannot be null.");
            return parent.GetVisualChildren().Flatten(item => item.GetVisualChildren()).OfType();
        }

public static IEnumerable Flatten(this IEnumerable items, Func> childSelector)
        {
            if (items == null) return Enumerable.Empty();
            return items.Concat(items.SelectMany(i => childSelector(i).Flatten(childSelector)));
        }

internal static IEnumerable GetVisualChildren(this DependencyObject parent)
        {
            int childCount = VisualTreeHelper.GetChildrenCount(parent);
            for (int counter = 0; counter < childCount; counter++)
            {
                yield return VisualTreeHelper.GetChild(parent, counter);
            }
        }
}


0


TreeView`の SelectedItemChanged`イベントを処理した後、このコードをビヘイビアーに配置します(コードビハインドでも機能します)。

var offset = this.HorizontalScrollOffsetAfterSelect; // would be 0 if you don't want to make that adjustable
if (!Double.IsNaN(offset))
{
    var scrollViewer = trv.GetVisualDescendants().OfType().FirstOrDefault();
    if (scrollViewer != null)
    {
        scrollViewer.ScrollToHorizontalOffset(offset);
        // and because that wasn't enough because of timing issues:
        var scrollBar = scrollViewer.GetVisualDescendants().OfType().Where(cur => cur.Orientation == Orientation.Horizontal).FirstOrDefault();
        if (scrollBar != null)
        {
            RoutedPropertyChangedEventHandler handler = null;
            handler = (sender, e) =>
                {
                    scrollBar.ValueChanged -= handler;

                    scrollViewer.ScrollToHorizontalOffset(offset);
                };
            scrollBar.ValueChanged += handler;
        }
    }
}

「System.Linqを使用」、「System.Windows.Controls.Primitivesを使用」、およびToolkit ofcが必要です。

これまでのところ私にとっては十分に機能します。