从Blend中复制TabControl的标准模板到vs2010,除了删除三个TabStripPlacement触发器外,没做其他修改,但应用该模板后,就发生如下图所示的怪异现象,不知是啥原因。(win7 64位的系统,vs专业版,没打补丁)
代码如下:
<Window x:Class="WpfApplication3.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <ControlTemplate x:Key="myTemp" TargetType="{x:Type TabControl}"> <Grid ClipToBounds="true" KeyboardNavigation.TabNavigation="Local" SnapsToDevicePixels="true"> <Grid.ColumnDefinitions> <ColumnDefinition x:Name="ColumnDefinition0" /> <ColumnDefinition x:Name="ColumnDefinition1" Width="0" /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition x:Name="RowDefinition0" Height="Auto" /> <RowDefinition x:Name="RowDefinition1" Height="*" /> </Grid.RowDefinitions> <TabPanel x:Name="HeaderPanel" Grid.Column="0" Grid.Row="0" Margin="2,2,2,0" Panel.ZIndex="1" IsItemsHost="true" KeyboardNavigation.TabIndex="1" /> <Border x:Name="ContentPanel" Grid.Column="0" Grid.Row="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local"> <ContentPresenter x:Name="PART_SelectedContentHost" Margin="{TemplateBinding Padding}" ContentSource="SelectedContent" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> </Border> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Window.Resources> <Grid Height="255" Width="365" > <TabControl Template="{StaticResource myTemp}" Height="206" Margin="50,23,0,0" Name="tabControl1" Width="220"> <TabItem Header="tabItem1" Name="tabItem1"> <Button Content="Button" Height="42" Name="button1" Width="94" /> </TabItem> </TabControl> </Grid> </Window>
首先要弄明白你删掉的代码是做什么用的
<ControlTemplate.Triggers> <Trigger Property="TabStripPlacement" Value="Bottom"> <Setter Property="Grid.Row" TargetName="headerPanel" Value="1"/> <Setter Property="Grid.Row" TargetName="contentPanel" Value="0"/> <Setter Property="Height" TargetName="RowDefinition0" Value="*"/> <Setter Property="Height" TargetName="RowDefinition1" Value="Auto"/> <Setter Property="Margin" TargetName="headerPanel" Value="2,0,2,2"/> </Trigger> <Trigger Property="TabStripPlacement" Value="Left"> <Setter Property="Grid.Row" TargetName="headerPanel" Value="0"/> <Setter Property="Grid.Row" TargetName="contentPanel" Value="0"/> <Setter Property="Grid.Column" TargetName="headerPanel" Value="0"/> <Setter Property="Grid.Column" TargetName="contentPanel" Value="1"/> <Setter Property="Width" TargetName="ColumnDefinition0" Value="Auto"/> <Setter Property="Width" TargetName="ColumnDefinition1" Value="*"/> <Setter Property="Height" TargetName="RowDefinition0" Value="*"/> <Setter Property="Height" TargetName="RowDefinition1" Value="0"/> <Setter Property="Margin" TargetName="headerPanel" Value="2,2,0,2"/> </Trigger> <Trigger Property="TabStripPlacement" Value="Right"> <Setter Property="Grid.Row" TargetName="headerPanel" Value="0"/> <Setter Property="Grid.Row" TargetName="contentPanel" Value="0"/> <Setter Property="Grid.Column" TargetName="headerPanel" Value="1"/> <Setter Property="Grid.Column" TargetName="contentPanel" Value="0"/> <Setter Property="Width" TargetName="ColumnDefinition0" Value="*"/> <Setter Property="Width" TargetName="ColumnDefinition1" Value="Auto"/> <Setter Property="Height" TargetName="RowDefinition0" Value="*"/> <Setter Property="Height" TargetName="RowDefinition1" Value="0"/> <Setter Property="Margin" TargetName="headerPanel" Value="0,2,2,2"/> </Trigger>
TabStripPlacement是用来设置TabItem标签头的对齐方式(默认是TOP)。参考http://www.cnblogs.com/Kinglee/archive/2009/08/07/1541525.html
这些触发器就是用于设置TabItem布局,你可以看到在触发器中有设置Head和content的位置(Row),高度宽度以及margin。删掉了这些触发器,TabItem的布局位置就没有了,也就是会认为TabItem的Head和Content都会从坐标(0,0)开始。所以TabItem的内容就会错位,错位的偏移大小刚好就是TabItem的Head的大小。
在vs2010中,你可以把代码修改成下面这样,即修改TabItem的高度和宽度为0,为了方便观看,把TabItem的内容用蓝色Grid填充。
<TabControl Template="{StaticResource myTemp}" Height="206" TabStripPlacement="Top" Margin="137,69,146,36" Name="tabControl1" Width="220" Padding="0"> <TabItem Header="tabItem1" Name="tabItem1" Width="0" Height="0" > <Grid Background="Blue"/> </TabItem> </TabControl>
这时候点击Grid可以看到选择框的偏移消失了。也就是说你在Button中看到的选择框偏移其实就是TabItem占用的。
看到这里可能也发现了,默认的Tabitem对齐方式是TOP,但是删掉的三个触发器中是Left,right和bottom,没有删除Top,但是却对显示产生影响了。影响仅仅是选择框偏移,但实际控件并没有偏移。
这其实是VS2010的小Bug,在VS2012中,这个问题已经被处理了。
可以看看同样的代码在VS2010(上图)和2012(下图)的显示区别
所以结论就是,在vs2010中不要更改那三个Trigger,如果更改了,其实是没有影响的,就是显示会有偏差,如果在vs2012下那就没有问题了
非常感谢您如此详细的解答,谢谢!
回头换成vs2012好了。
与 TabControl 的 Padding 设置有关
设置 Padding是可以解决,但我是想搞明白,复制的就是系统的标准模板,为何使用默认的就没问题,用复制的就有问题。