用RadioButton替换TabItem

时间:2014-01-10 13:52:42

标签: wpf prism

我正在使用Prism进行UI组合,并且需要一种通过RadioButton切换活动视图的方法。我想要一组RadioButtons,它会在选中时改变所需的视图。我认为TabControl对此非常完美。我以为我可以使用样式将TabItem的模板更改为RadioButton,但是不选择RadioButton切换选项卡。这是我对TabItem

的模板
<ControlTemplate TargetType="{x:Type TabItem}">
    <RadioButton IsChecked="{TemplateBinding IsSelected}"
                 Content="{TemplateBinding Header}" />
</ControlTemplate>

我认为应该在选中RadioButton时选中标签,但这似乎不会发生。我做错了什么或者有其他方法可以达到相同的结果吗?

还有一种方法可以使TabControl的第一个视图处于活动状态吗?我在选项卡控件上尝试了SelectedIndex =“0”,但这似乎没有在视图上设置IActiveAware.IsActive。

以下是我用于设置TabControl和TabItem样式的确切代码

    <Style TargetType="{x:Type TabItem}">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="Foreground" Value="{StaticResource mainRegionControlForegroundBrush}"></Setter>
        <Setter Property="Header" Value="{Binding Content.DataContext.Title, RelativeSource={RelativeSource Self}}"/>
        <Setter Property="Margin" Value="2"/>
        <Setter Property="SnapsToDevicePixels" Value="True"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabItem}">
                    <RadioButton IsChecked="{TemplateBinding IsSelected}" Content="{TemplateBinding Header}" Foreground="{TemplateBinding Foreground}" Margin="{TemplateBinding Margin}"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style TargetType="{x:Type TabControl}">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabControl}">
                    <Grid KeyboardNavigation.TabNavigation="Local" ClipToBounds="True" SnapsToDevicePixels="True">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>
                        <StackPanel IsItemsHost="True" Orientation="Horizontal" Margin="10,0"/>
                        <ContentPresenter Grid.Row="1" Name="PART_SelectedContentHost" Content="{TemplateBinding TabControl.SelectedContent}" ContentSource="SelectedContent" ContentTemplate="{TemplateBinding TabControl.SelectedContentTemplate}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"></ContentPresenter>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

2 个答案:

答案 0 :(得分:2)

我明白了。 TemplateBinding没有更新父属性,因此从未在TabItem上设置IsSelected。我将绑定更改为

IsChecked="{Binding IsSelected, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"

并且有效。

答案 1 :(得分:1)

您只需为使用ControlTemplate元素的RadioButton定义新的Border

enter image description here

<StackPanel Orientation="Horizontal">
    <StackPanel.Resources>
        <ControlTemplate x:Key="TabTemplate" TargetType="{x:Type RadioButton}">
            <Border BorderBrush="Black" Background="{TemplateBinding Background}" 
BorderThickness="1,1,1,0" CornerRadius="5,5,0,0" Padding="5">
                <ContentPresenter Content="{TemplateBinding Content}" />
            </Border>
        </ControlTemplate>
        <Style TargetType="{x:Type RadioButton}">
            <Setter Property="Template" Value="{StaticResource TabTemplate}" />
            <Setter Property="Height" Value="26" />
            <Style.Triggers>
                <Trigger Property="IsChecked" Value="True">
                    <Setter Property="Background" Value="LightGray" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </StackPanel.Resources>
    <RadioButton Content="Tab 1" />
    <RadioButton Content="Tab 2" />
    <RadioButton Content="Tab 3" />
</StackPanel>

我还添加了一个基本Trigger,以便您可以看到Style所选项目与其他标签的区别。


更新&gt;&gt;&gt;

抱歉,我显然没有正确阅读你的问题。反过来说,这是一项更多的工作,不幸的是,将不得不做你的一点,因为代码太多了。首先,您的示例代码无效,因为您尝试为ControlTemplate定义新的TabControl,而您实际只需要为其定义一个TabItem

执行此操作的第一步是为整个ControlTemplate实际定义新TabControl,其中包含 ControlTemplate TabItem 。您的示例无效,因为您无法复制默认ControlTemplate的大部分内容,因此我们需要这样做。怎么样?好吧,我们可以在MSDN上的TabControl Styles and Templates页面找到默认的ControlTemplate

所以看了之后,你会理解为什么我不能把所有代码放在这里。首先,你基本上需要使用那个确切的XAML来重现默认的ControlTemplate ...当它正常工作时,然后你可以开始根据你的要求进行调整。如果你向下看链接页面,你会看到:

<Style TargetType="{x:Type TabItem}">
    <Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type TabItem}">
            ...

这是ControlTemplate的默认TabItem开始的位置。进一步向下看,在VisualStateManager.VisualStateGroups下面,您应该看到:

      <Border x:Name="Border"
              Margin="0,0,-4,0"
              BorderThickness="1,1,1,1"
              CornerRadius="2,12,0,0">
        <Border.BorderBrush>
          <SolidColorBrush Color="{DynamicResource BorderMediumColor}" />
        </Border.BorderBrush>
        <Border.Background>

          <LinearGradientBrush StartPoint="0,0"
                               EndPoint="0,1">
            <LinearGradientBrush.GradientStops>
              <GradientStopCollection>
                <GradientStop Color="{DynamicResource ControlLightColor}"
                              Offset="0.0" />
                <GradientStop Color="{DynamicResource ControlMediumColor}"
                              Offset="1.0" />
              </GradientStopCollection>
            </LinearGradientBrush.GradientStops>
          </LinearGradientBrush>

        </Border.Background>
        <ContentPresenter x:Name="ContentSite"
                          VerticalAlignment="Center"
                          HorizontalAlignment="Center"
                          ContentSource="Header"
                          Margin="12,2,12,2"
                          RecognizesAccessKey="True" />
      </Border>

定义了TabItem应该是什么样子,是您需要添加RadioButton(而不是此Border及其内容)的地方。您可能还需要删除或调整引用旧控件的任何内容,例如。在VisualStateManager.VisualStateGroups部分。