WPF:在ScrollViewer

时间:2017-09-20 08:03:29

标签: wpf

我有一个TabControl,其样式和模板的方式是标签页眉和标签内容用一行分隔,但当前选中的标签会打破这一行(见图1)。{{3 }}

除了两件事之外,这就像魅力一样。

第一个问题:在某些缩放状态下(不幸的是在默认状态下也是100%),有一条很细的线将标签标题与内容分开(见图2;分离的高度) line是2px)。enter image description here

它来自哪里,如何摆脱它?

由于当前选中的标签可能会在以后显示左,上,右边框,因此我不能只增加负边距,因为左边框和右边框在内容中可见。

第二个问题:如果我将标签页放在ScrollViewer内以便能够水平滚动标签(如果有太多标签),则为负Margin被剪裁并显示分隔线。 当然,ScrollViewer的样式和模板设计方式是不使用内容下方的水平滚动条。

如何在Margin内使用否定ScrollViewer

我在下面的代码中注释掉了ScrollViewer。请删除评论指标,并移除MarginTabPanel上的ScrollViewer,以查看问题的实际效果。

这是我的样式,模板和代码,以防有人需要它:

<Style x:Key="TabControlStyle" TargetType="{x:Type TabControl}">
    <Setter Property="Background" Value="LightGoldenrodYellow" />
    <Setter Property="BorderBrush" Value="Gray" />
    <Setter Property="BorderThickness" Value="0" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabControl}">
                <Grid SnapsToDevicePixels="True"
                      Background="{TemplateBinding Background}">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>

                    <Border x:Name="Content"
                            Grid.Row="1" Grid.Column="0"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="0,2,0,0"
                            Background="White">
                        <ContentPresenter x:Name="PART_SelectedContentHost"
                                          ContentSource="SelectedContent"
                                          Margin="{TemplateBinding Padding}"
                                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                    </Border>

                    <!--<ScrollViewer Grid.Row="0" Grid.Column="0" Margin="5,5,5,0">-->
                    <TabPanel x:Name="PART_ScrollContentPresenter"
                              Grid.Row="0" Grid.Column="0"
                              Margin="5,5,5,0"
                              IsItemsHost="True" />
                    <!--</ScrollViewer>-->
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Style x:Key="TabItemStyle" TargetType="{x:Type TabItem}">
    <Setter Property="Background" Value="LightGray" />
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="BorderThickness" Value="1,1,1,0" />
    <Setter Property="BorderBrush" Value="Gray" />
    <Setter Property="MinWidth" Value="50" />
    <Setter Property="Margin" Value="0,0,5,0" />
    <Setter Property="Padding" Value="0" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabItem}">
                <Grid SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                      Margin="{TemplateBinding Margin}">
                    <Border x:Name="Border"
                            Background="{TemplateBinding Background}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            BorderBrush="{TemplateBinding Background}">

                        <TextBlock x:Name="TabTitle"
                                   Margin="16,6"
                                   Text="{TemplateBinding Header}"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Center"
                                   TextWrapping="NoWrap" 
                                   TextTrimming="CharacterEllipsis" />
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Background" Value="White" TargetName="Border" />
                        <Setter Property="BorderBrush" Value="Gray" TargetName="Border" />
                        <Setter Property="Margin" Value="0,0,2,-2" />
                        <Setter Property="Padding" Value="0,-2,0,0" />
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsMouseOver" Value="True" />
                            <Condition Property="IsSelected" Value="False" />
                        </MultiTrigger.Conditions>
                        <Setter Property="Background" Value="Gray" TargetName="Border" />
                        <Setter Property="BorderBrush" Value="Gray" TargetName="Border" />
                    </MultiTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication" 
        Title="MainWindow"
        Height="350" Width="525">

    <Window.LayoutTransform>
        <ScaleTransform ScaleX="1" ScaleY="1" />
    </Window.LayoutTransform>

    <TabControl Style="{StaticResource TabControlStyle}"
                ItemContainerStyle="{StaticResource TabItemStyle}">
        <TabItem Header="Tab 1" />
        <TabItem Header="Tab Two" />
        <TabItem Header="Tab III" />
    </TabControl>

</Window>

感谢您的时间和帮助。

1 个答案:

答案 0 :(得分:1)

关于第一个问题,您可以通过将边框与内容分开来增加负边距:

<Grid SnapsToDevicePixels="True" Background="{TemplateBinding Background}">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <!--SeparatorLine will be rendered on bottom-->
    <Border x:Name="SeparatorLine"
            Grid.Row="1" Grid.Column="0"
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="0,2,0,0">
    </Border>

    <!--Tabs will be rendered on top of the SeparatorLine-->
    <TabPanel x:Name="PART_ScrollContentPresenter"
            Grid.Row="0" Grid.Column="0"
            Margin="5,5,5,0"
            IsItemsHost="True" />

    <!--Content will be rendered on top. Content.Margin should equal the SeparatorLine.BorderThickness-->
    <Border x:Name="Content"
            Grid.Row="1" Grid.Column="0"
            Margin="0,2,0,0"
            Background="White">
        <ContentPresenter x:Name="PART_SelectedContentHost"
                          ContentSource="SelectedContent"
                          Margin="{TemplateBinding Padding}"
                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
    </Border>
</Grid>

现在,您可以在TabItem中使用大于内容边框大小的负边距。

第二个问题也可以通过负边距来解决...据我所知,你不会得到默认的Scrollviewer来允许任何内容溢出,无论你想要多么糟糕。有关该主题的一些讨论,请参阅WPF clipping even when no clipping is desired - how to turn it off?

您可以做的是使用负边距增加滚动查看器大小,因此实际项目将保留在支持区域内:

<ScrollViewer Grid.Row="0" Grid.Column="0" Margin="5,5,5,-3" VerticalScrollBarVisibility="Disabled">
    <TabPanel x:Name="PART_ScrollContentPresenter"
            Grid.Row="0" Grid.Column="0"
            Margin="0,0,0,3"
            IsItemsHost="True" />
</ScrollViewer>

此示例允许TabItem上的负底边距最多3 px。