WPF ControlTemplate для прокрутки Управления TreeView

Вам нужно изменить ai: '' на ai: []

С

data: {
  ai: ''
}

на

data: {
  ai: []
}

. документация ,

5
задан Ben Collins 28 October 2008 в 21:26
поделиться

5 ответов

Объекты прокручивают, потому что 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();
    }
}
7
ответ дан 18 December 2019 в 14:53
поделиться

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

Кажется, что это - взаимодействие с scrollviewer и системой фокуса.

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

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

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

0
ответ дан 18 December 2019 в 14:53
поделиться

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

        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>

Который, к сожалению, не выглядит полезным. Я не вижу свойств там для остановки auto-scroll-focus вещи.

Все еще взгляд...

0
ответ дан 18 December 2019 в 14:53
поделиться

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

0
ответ дан 18 December 2019 в 14:53
поделиться

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

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;
        };

    }
}

}

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

6
ответ дан 18 December 2019 в 14:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: