WPF ControlTemplate для прокрутки TreeView Control - PullRequest
5 голосов
/ 29 октября 2008

Я использую элемент управления TreeView, и он автоматически прокручивается, чтобы выровнять TreeViewItem по левому краю при нажатии одной из них. Я просмотрел свои стили и шаблоны шаблонов, но ничего не нашел. Существует ли ControlTemplate по умолчанию, который вызывает это? Я хочу отключить его.

Ответы [ 5 ]

7 голосов
/ 04 ноября 2008

Элементы прокручиваются, потому что ScrollViewer вызывает BringIntoView () для них. Таким образом, один из способов избежать прокрутки - это подавить обработку события RequestBringIntoView. Вы можете попробовать это быстро, создав подкласс TreeView и создав вместо него этот элемент управления:

public class NoScrollTreeView : TreeView
{
    public class NoScrollTreeViewItem : TreeViewItem
    {
        public NoScrollTreeViewItem() : base()
        {
            this.RequestBringIntoView += delegate (object sender, RequestBringIntoViewEventArgs e) {
                e.Handled = true;
            };
        }

        protected override DependencyObject GetContainerForItemOverride()
        {
            return new NoScrollTreeViewItem();
        }
    }
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new NoScrollTreeViewItem();
    }
}
6 голосов
/ 10 июня 2009

потратив несколько часов на эту проблему, я нашел решение, которое работает для меня.

Решение brians для предотвращения пузырькового события RequestBringIntoView на TreeViewItem было первым шагом. к сожалению, это также останавливает отображение дерева, если вы изменяете выбранный элемент программно на

yourtreeview.SelectedItem = yourtreeviewitem

так, для меня решение состоит в том, чтобы изменить шаблон управления древовидной структуры следующим образом:

<Style x:Key="{x:Type TreeView}" TargetType="TreeView">
        <Setter Property="OverridesDefaultStyle" Value="True" />
        <Setter Property="SnapsToDevicePixels" Value="True" />
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
        <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="TreeView">
                    <Border Name="Border" BorderThickness="0" Padding="0" Margin="1">
                        <ScrollViewer Focusable="False" CanContentScroll="False" Padding="0">
                            <Components:AutoScrollPreventer Margin="0">
                                <ItemsPresenter/>
                            </Components:AutoScrollPreventer>
                        </ScrollViewer>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

"autoscrollpreventer":

using System;
using System.Windows;
using System.Windows.Controls;

namespace LiveContext.Designer.GUI.Components {
    public class AutoScrollPreventer : StackPanel
    {
    public AutoScrollPreventer() {

        this.RequestBringIntoView += delegate(object sender, RequestBringIntoViewEventArgs e)
        {
            // stop this event from bubbling so that a scrollviewer doesn't try to BringIntoView..
            e.Handled = true;
        };

    }
}

}

надеюсь, это поможет ..

0 голосов
/ 29 октября 2008

Хорошо, я наконец смог получить стиль по умолчанию, подобный этому:

        using (Stream sw = File.Open(@"C:\TreeViewDefaults.xaml", FileMode.Truncate, FileAccess.Write))
        {
            Style ts = Application.Current.FindResource(typeof(TreeView)) as Style;
            if (ts != null)
                XamlWriter.Save(ts, sw);
        }

Который произвел:

<Style TargetType="TreeView" 
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:s="clr-namespace:System;assembly=mscorlib" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style.Triggers>
        <Trigger Property="VirtualizingStackPanel.IsVirtualizing">
            <Setter Property="ItemsControl.ItemsPanel">
                <Setter.Value>
                    <ItemsPanelTemplate><VirtualizingStackPanel IsItemsHost="True" /></ItemsPanelTemplate>
                </Setter.Value>
            </Setter>
            <Trigger.Value>
                <s:Boolean>True</s:Boolean>
            </Trigger.Value>
        </Trigger>
    </Style.Triggers>
    <Style.Resources>
        <ResourceDictionary />
    </Style.Resources>
    <Setter Property="Panel.Background">
        <Setter.Value><DynamicResource ResourceKey="{x:Static SystemColors.WindowBrushKey}" /></Setter.Value>
    </Setter>
    <Setter Property="Border.BorderBrush">
        <Setter.Value><SolidColorBrush>#FF828790</SolidColorBrush></Setter.Value>
    </Setter>
    <Setter Property="Border.BorderThickness">
        <Setter.Value><Thickness>1,1,1,1</Thickness></Setter.Value>
    </Setter>
    <Setter Property="Control.Padding">
        <Setter.Value><Thickness>1,1,1,1</Thickness></Setter.Value>
    </Setter>
    <Setter Property="TextElement.Foreground">
        <Setter.Value><DynamicResource ResourceKey="{x:Static SystemColors.ControlTextBrushKey}" /></Setter.Value>
    </Setter>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility">
        <Setter.Value><x:Static Member="ScrollBarVisibility.Auto" /></Setter.Value>
    </Setter>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility">
        <Setter.Value><x:Static Member="ScrollBarVisibility.Auto" /></Setter.Value>
    </Setter>
    <Setter Property="Control.VerticalContentAlignment">
        <Setter.Value><x:Static Member="VerticalAlignment.Center" /></Setter.Value>
    </Setter>
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate TargetType="TreeView">
                <Border BorderThickness="{TemplateBinding Border.BorderThickness}" 
                        BorderBrush="{TemplateBinding Border.BorderBrush}" 
                        Name="Bd" SnapsToDevicePixels="True">
                    <ScrollViewer CanContentScroll="False" 
                                  HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" 
                                  VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" 
                                  Background="{TemplateBinding Panel.Background}" 
                                  Padding="{TemplateBinding Control.Padding}" 
                                  Name="_tv_scrollviewer_" 
                                  SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" 
                                  Focusable="False">
                        <ItemsPresenter />
                    </ScrollViewer>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="UIElement.IsEnabled">
                        <Setter Property="Panel.Background" TargetName="Bd">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.ControlBrushKey}" />
                            </Setter.Value>
                        </Setter>
                        <Trigger.Value>
                            <s:Boolean>False</s:Boolean>
                        </Trigger.Value>
                    </Trigger>
                    <Trigger Property="VirtualizingStackPanel.IsVirtualizing">
                        <Setter Property="ScrollViewer.CanContentScroll" TargetName="_tv_scrollviewer_">
                            <Setter.Value><s:Boolean>True</s:Boolean></Setter.Value>
                        </Setter>
                        <Trigger.Value>
                            <s:Boolean>True</s:Boolean>
                        </Trigger.Value>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Что, к сожалению, не выглядит полезным. Я не вижу там никаких свойств для остановки функции авто-прокрутки.

Все еще смотрю ...

0 голосов
/ 30 октября 2008

Еще один забавный лакомый кусочек: существует переопределенное логическое значение, называемое HandlesScrolling, которое всегда возвращает true. После декомпиляции источника похоже, что это свойство НИКОГДА не используется (или оно используется в каком-то глубоком, темном, секретном месте в XAML). Я попытался создать собственный элемент управления TreeView, чтобы установить для этого значения значение false, и оно не сработало.

0 голосов
/ 29 октября 2008

Похоже, я нашел хорошую подсказку на MSDN :

Похоже, это взаимодействие с прокрутки и фокус система.

Когда элемент фокусируется внутри ScrollViewer (который является частью Шаблон TreeView), ScrollViewer поручено сделать элемент видимый. Он автоматически отвечает прокрутка до запрошенного элемента.

Методы внутри ScrollViewer которые обрабатывают эти запросы фокуса все личное и / или внутреннее, чтобы вы действительно не могу добраться до них. Я не думаю, что вы слишком много можете сделать в этот случай; это просто, как работает фокус.

Итак, это так? Конечно, есть способ изменить шаблон TreeView, чтобы ScrollViewer не имел такого поведения ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...