Wpf 用RadioButton替换TabItem

Wpf 用RadioButton替换TabItem,wpf,prism,Wpf,Prism,我正在使用Prism进行UI合成,需要一种通过单选按钮切换活动视图的方法。我想要一组单选按钮,选中时可以更改所需的视图。我认为TabControl非常适合这个。我以为我可以使用一种样式将TabItem的模板更改为RadioButton,但它不能在RadioButton被选中时切换选项卡。这是我为TabItem准备的模板 <ControlTemplate TargetType="{x:Type TabItem}"> <RadioButton IsChecked="{Tem

我正在使用Prism进行UI合成,需要一种通过单选按钮切换活动视图的方法。我想要一组单选按钮,选中时可以更改所需的视图。我认为TabControl非常适合这个。我以为我可以使用一种样式将TabItem的模板更改为RadioButton,但它不能在RadioButton被选中时切换选项卡。这是我为TabItem准备的模板

<ControlTemplate TargetType="{x:Type TabItem}">
    <RadioButton IsChecked="{TemplateBinding IsSelected}"
                 Content="{TemplateBinding Header}" />
</ControlTemplate>
我认为当选中单选按钮时,应该选择选项卡,但这似乎没有发生。我做错了什么,或者有没有其他方法可以达到同样的结果

还有没有办法激活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>

您只需为使用边框元素的RadioButton定义一个新的ControlTemplate:

这是TabItem的默认ControlTemplate开始的地方。再往下看,在VisualStateManager.VisualStateGroups下面,您应该看到:

<Style TargetType="{x:Type TabItem}">
    <Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type TabItem}">
            ...
      <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而不是此边框及其内容的地方。您可能还需要删除或调整引用旧控件的任何内容,例如VisualStateManager.VisualStateGroups部分中的内容。

您只需为使用边框元素的RadioButton定义一个新的控件模板:

这是TabItem的默认ControlTemplate开始的地方。再往下看,在VisualStateManager.VisualStateGroups下面,您应该看到:

<Style TargetType="{x:Type TabItem}">
    <Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type TabItem}">
            ...
      <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而不是此边框及其内容的地方。您可能还需要删除或调整引用旧控件的任何内容,例如VisualStateManager.VisualStateGroups部分中的内容。

我找到了答案。TemplateBinding没有更新父属性,因此从未在TabItem上设置IsSelected。我把装订改成了

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

它成功了。

我明白了。TemplateBinding没有更新父属性,因此从未在TabItem上设置IsSelected。我把装订改成了

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

它成功了。

实际上我正试图做相反的事情,将选项卡项设置为单选按钮。谢谢。那么,我是否需要复制单选按钮的外观,而不使用实际的单选按钮作为tabitem的控件模板?我在问题中发布了选项卡控件的样式。不,您可以使用实际的单选按钮。因此,如果您查看我在问题中发布的更新代码,我做错了什么?我可以让RadioButton正确显示,但是当它被点击时,什么也没有发生。它不会更改选项卡控件的内容。如果我从TabItem样式中删除模板,TabItem将正常工作。我不知道。。。Visual Studio中的“输出”窗口中有哪些错误?实际上我正试图做相反的事情,将选项卡项样式设置为RadioButton。谢谢。那么,我是否需要复制单选按钮的外观,而不使用实际的单选按钮作为tabitem的控件模板?我在问题中发布了选项卡控件的样式。不,您可以使用实际的单选按钮。因此,如果您查看我在问题中发布的更新代码,我做错了什么?我可以让RadioButton正确显示,但是当它被点击时,什么也没有发生。它不会更改选项卡控件的内容。如果我从TabItem样式中删除模板,TabItem将正常工作。我不知道。。。Visual Studio中的输出窗口中有哪些错误?