Creating tabs in WinRT

前端 未结 4 765
南方客
南方客 2021-02-01 20:04

I\'m working on a C#/XAML Metro style app for Windows 8. The XAML in WinRT does not have a \"tab\" control. However, I\'m trying to emulate the way a result in the Windows 8 sto

相关标签:
4条回答
  • 2021-02-01 20:54

    The FlipView control might meet your needs. Sample.

    0 讨论(0)
  • 2021-02-01 20:58

    I used FlipView control as well, but I created a separate templated control which is inherited from FlipView.

    The main idea is to override default FlipView ControlTemplate: I added a ListBox which represents tab headers and removed "Next" and "Previous" FlipView buttons.

    I can share source code if you need more details about my implementation.

    0 讨论(0)
  • 2021-02-01 21:01

    Here is the style to use for radio buttons to make them look/work like tabs:

        <!-- Style for radio buttons used as tab control -->
    <Style x:Key="TabRadioButtonStyle" TargetType="RadioButton">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="RadioButton">
                    <Grid>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CheckStates">
                                <VisualState x:Name="Unchecked">
                                    <Storyboard>
                                        <ColorAnimation Duration="0" To="Gray" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="TabButtonText" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Indeterminate">
                                    <Storyboard>
                                        <ColorAnimation Duration="0" To="White" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="TabButtonText" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Checked">
                                    <Storyboard>
                                        <ColorAnimation Duration="0" To="Black" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)" Storyboard.TargetName="TabButtonText" />
                                    </Storyboard>
                                </VisualState>
    
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <TextBlock x:Name="TabButtonText" Text="{TemplateBinding Content}" Style="{StaticResource GroupHeaderTextStyle}" HorizontalAlignment="Left"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    You can then define a grid to hold the tab stack panel and a frame to hold the content associated with each tab. Use Click event on the radio buttons to navigate the frame to the appropriate pages for each "tab".

     <Grid Grid.Row="1"
            Margin="120,0,56,56">
            <!-- Row 1 to hold the "Tabs", Row 2 to hold the content -->
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <StackPanel Grid.Row="0" Orientation="Horizontal">
                <RadioButton x:Name="Tab1" Content="Tab1" Style="{StaticResource TabRadioButtonStyle}" IsChecked="True" Click="Tab1_Clicked" />
                <RadioButton x:Name="Tab2" Content="Tab2" Style="{StaticResource TabRadioButtonStyle}" IsChecked="False" Click="Tab2_Clicked" Margin="30,0,0,0" />
                <RadioButton x:Name="Tab3" Content="Tab3" Style="{StaticResource TabRadioButtonStyle}" IsChecked="False" Click="Tab3_Clicked" Margin="30,0,0,0"/>
            </StackPanel>
            <Frame x:Name="ContentFrame" Margin="0,20,0,0" Grid.Row="1" Background="{StaticResource SandstormBackgroundBrush}" Loaded="ContentFrame_Loaded" />
        </Grid>
    
    0 讨论(0)
  • 2021-02-01 21:07

    Styling a ListBox is preferable to styling a radio button group.

    The following code uses a ListBox with a horizontal stack panel to create the tab item header. A ContentControl displays the tab content as a user control.

    I've only tested this with WPF, but hopefully it will work on WinRT.

    enter image description here

    <Page.Resources>
        <Style TargetType="ListBoxItem">
            <!-- disable default selection highlight -->
            <!-- Style.Resources is not supported in WinRT -->
            <!--<Style.Resources>
                --><!-- SelectedItem with focus --><!--
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" 
                                Color="Transparent" />
                --><!-- SelectedItem without focus --><!--
                <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" 
                                Color="Transparent" />
            </Style.Resources>-->
            <!--Setter Property="FocusVisualStyle" is not supported in WinRT -->
            <!--<Setter Property="FocusVisualStyle" Value="{x:Null}" />-->
        </Style>
        <Style x:Key="TitleStyle" TargetType="TextBlock">
            <Setter Property="Foreground" Value="LightGray"/>
            <!--Style.Triggers is not supported in WinRT-->
            <!--<Style.Triggers>
                <DataTrigger Value="True" Binding="{Binding Path=IsSelected, 
                            RelativeSource={RelativeSource Mode=FindAncestor, 
                            AncestorType={x:Type ListBoxItem}}}">
                    <Setter Property="Foreground" Value="DarkGray"/>
                    <Setter Property="FontWeight" Value="Bold"/>
                </DataTrigger>
            </Style.Triggers>-->
        </Style>
    </Page.Resources>
    <Grid>
        <Grid.DataContext>
            <ViewModel:TestPage/>
        </Grid.DataContext>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
    
        <ListBox x:Name="tabListBox" Grid.Row="0" ItemsSource="{Binding Items}" 
                            SelectedItem="{Binding SelectedItem, Mode=TwoWay}" 
                            BorderBrush="{x:Null}" BorderThickness="0">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Title}" Margin="5" 
                            Style="{StaticResource TitleStyle}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    
        <ContentControl Grid.Row="1" Content="{Binding SelectedItem.Content}"/>
    </Grid>
    

    View model

    public class MyTabViewModel : INotifyPropertyChanged
    {
        public MyTabViewModel()
        {
            Items =
                new List<MyTabItem>
                    {
                        new MyTabItem
                            {
                                Title = "Overview",
                                Content = new UserControl1()
                            },
                        new MyTabItem
                            {
                                Title = "Detail",
                                Content = new UserControl2()
                            },
                        new MyTabItem
                            {
                                Title = "Reviews",
                                Content = new UserControl3()
                            },
                    };
        }
    
        public IEnumerable<MyTabItem> Items { get; private set; }
    
        private MyTabItem _selectedItem;
    
        public MyTabItem SelectedItem
        {
            get { return _selectedItem; }
            set
            {
                _selectedItem = value;
                PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem"));
            }
        }
    
        #region Implementation of INotifyPropertyChanged
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        #endregion
    }
    
    public class MyTabItem
    {
        public string Title { get; set; }
        public UserControl Content { get; set; }
    }
    
    0 讨论(0)
提交回复
热议问题