2008-10-28 77 views
5

我正在使用TreeView控件,当它单击其中一个时,它会自动滚动到左对齐TreeViewItem。我已经看了我的样式和控制模板,但我没有找到任何东西。有没有一个默认的ControlTemplate导致这个?我想禁用它。用于滚动TreeView控件的WPF ControlTemplate

回答

7

由于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(); 
    } 
} 
0

它看起来像我找到了一个很好的线索上MSDN

听起来这是一个互动 与ScrollViewer中,并重点 系统。

当元件被聚焦的 的ScrollViewer内(这是 TreeView的模板的一部分),所述的ScrollViewer 被指示以使元件 可见。它自动响应 滚动到请求的元素。

处理这些重点要求的ScrollViewer 的内部方法 所有私人和/或内部,所以你 真的不能得到他们。我不认为 这个案例太多,你可以在 中做;这只是焦点如何工作。

那么,是吗?当然还有一个办法修改TreeView的模板,使ScrollViewer中不会有这种行为......

0

好吧,我终于能够得到这样的默认样式:

 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

另一个有趣的花絮:有一个叫HandlesScrolling一个重写的布尔值,总是返回true。在反编译源代码之后,它看起来像这个属性从来没有使用过(或者它在XAML中的一些深色,黑暗,秘密的地方使用)。我试图让自己的TreeView控件将此值设置为false,但它不起作用。

+0

不错。我想我们可以去涉及.NET资源,但是......你知道的。 – 2008-10-30 12:06:54

6

在这个问题上花了一些时间后,我发现我工作的解决方案。

brians解决方案,以防止冒泡的TreeViewItem上的RequestBringIntoView事件是第一步。不幸的是,这也将停止,如果你通过

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

    } 
} 

}

希望我t帮助..

+0

非常好的解决方案。 – stijn 2012-01-17 20:31:44