为什么在样式中设置“模板”属性会破坏滚动?

时间:2011-03-21 01:32:16

标签: wpf scrollbar styles

我正在使用this sample创建一个多列树视图,我注意到滚动不再适用于此列表视图:

Broken scrollbars

经过一些游戏,我发现破坏滚动条的位是TreeListView的“Template”属性的设置:

<Style TargetType="{x:Type l:TreeListView}">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type l:TreeListView}">
        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
          <DockPanel>
            <GridViewHeaderRowPresenter Columns="{StaticResource gvcc}" DockPanel.Dock="Top"/>
            <ItemsPresenter/>
          </DockPanel>
        </Border>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

注释掉上面的内容修复了滚动条(但显然意味着没有显示网格列标题)。事实上,我发现即使是以下模板也会破坏滚动条:

<Style TargetType="{x:Type l:TreeListView}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type l:TreeListView}">
                <ItemsPresenter/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

为什么会这样?

3 个答案:

答案 0 :(得分:1)

我认为这是因为您编辑了WPF定义的控件的模板。 并且它被定义为具有scrollBar。 您覆盖该模板而不添加该模板。

我不是百分百肯定的,但我想知道你为什么要开始使用控制模板? 也许您要编辑的是DataTemplate? DataTemplate决定如何呈现由数据绑定绑定的对象。

答案 1 :(得分:1)

您需要实现自己的滚动条,因为您要覆盖默认模板。

将ControlTemplate的ItemsPresenter包裹在ScrollViewer

答案 2 :(得分:0)

最后我通过自己添加滚动条来解决这个问题 - 最初我实现了这个nieve方式并且只是滚动原始内容,我发现如果我这样做,水平滚动条不能正常工作(标题没有滚动。)

相反,我使用Control Template Reference来确定基本控件的作用,并对ListView的wjat做了变化。

我现在可以看到为什么我在做这样的事情时需要设置整个模板 - 我认为简单的事实证明是完全特定于我的控制。

这是我的Xaml:

<Style x:Key="{x:Static local:TreeListView.ScrollViewerStyleKey}" TargetType="ScrollViewer">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ScrollViewer">
                <Grid Background="{TemplateBinding Background}">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <DockPanel Margin="{TemplateBinding Padding}">
                        <ScrollViewer DockPanel.Dock="Top"
                            HorizontalScrollBarVisibility="Hidden"
                            VerticalScrollBarVisibility="Hidden"
                            Focusable="false">
                            <GridViewHeaderRowPresenter Margin="2,0,2,0"
                                Columns="{Binding Path=TemplatedParent.Columns, 
                                    RelativeSource={RelativeSource TemplatedParent}}"
                                ColumnHeaderContainerStyle="{Binding
                                    Path=TemplatedParent.View.ColumnHeaderContainerStyle,
                                    RelativeSource={RelativeSource TemplatedParent}}"
                                ColumnHeaderTemplate="{Binding
                                    Path=TemplatedParent.View.ColumnHeaderTemplate,
                                    RelativeSource={RelativeSource TemplatedParent}}"
                                ColumnHeaderTemplateSelector="{Binding 
                                    Path=TemplatedParent.View.ColumnHeaderTemplateSelector,
                                    RelativeSource={RelativeSource TemplatedParent}}"
                                AllowsColumnReorder="{Binding
                                    Path=TemplatedParent.View.AllowsColumnReorder,
                                    RelativeSource={RelativeSource TemplatedParent}}"
                                ColumnHeaderContextMenu="{Binding
                                    Path=TemplatedParent.View.ColumnHeaderContextMenu,
                                    RelativeSource={RelativeSource TemplatedParent}}"
                                ColumnHeaderToolTip="{Binding
                                    Path=TemplatedParent.View.ColumnHeaderToolTip,
                                    RelativeSource={RelativeSource TemplatedParent}}"
                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </ScrollViewer>
                        <ScrollContentPresenter Name="PART_ScrollContentPresenter"
                            KeyboardNavigation.DirectionalNavigation="Local"
                            CanHorizontallyScroll="False"
                            CanVerticallyScroll="False" />
                    </DockPanel>
                    <ScrollBar Name="PART_HorizontalScrollBar"
                        Orientation="Horizontal"
                        Grid.Row="1"
                        Maximum="{TemplateBinding ScrollableWidth}"
                        ViewportSize="{TemplateBinding ViewportWidth}"
                        Value="{TemplateBinding HorizontalOffset}"
                        Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" />
                    <ScrollBar Name="PART_VerticalScrollBar"
                        Grid.Column="1"
                        Maximum="{TemplateBinding ScrollableHeight}"
                        ViewportSize="{TemplateBinding ViewportHeight}"
                        Value="{TemplateBinding VerticalOffset}"
                        Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Style TargetType="{x:Type local:TreeListView}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TreeView">
                <Border Name="Border" CornerRadius="1" BorderThickness="1">
                    <Border.BorderBrush>
                        <SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
                    </Border.BorderBrush>
                    <Border.Background>
                        <SolidColorBrush Color="{DynamicResource ControlLightColor}" />
                    </Border.Background>
                    <ScrollViewer Style="{DynamicResource {x:Static local:TreeListView.ScrollViewerStyleKey}}">
                        <ItemsPresenter />
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

以上要求我为控件本身添加一些额外的属性:

public static ResourceKey ScrollViewerStyleKey
{
    get
    {
        return new ComponentResourceKey(typeof(TreeListView), "TreeListView_ScrollViewerStyleKey");
    }
}