Как создавать анимированные вкладки с индикатором вкладок с помощью WPF?

#wpf #xaml #tabcontrol #separator #tabitem

#wpf #xaml #tabcontrol #разделитель #tabitem

Вопрос:

У меня есть элемент управления вкладками в моем приложении WPF. И этот элемент управления вкладкой имеет два элемента вкладки. И из-за цели дизайна я подчеркиваю каждый из элементов вкладки. Теперь я хочу анимировать подчеркивание этих элементов вкладки. Я просто хочу простую анимацию, когда я выбираю любой из этих элементов вкладки, подчеркивание должно быстро перемещаться с одного элемента вкладки на другой. Хотя между этими элементами вкладки есть приличное пространство.

Я реализую подчеркивание этих элементов вкладки с помощью оформления текста в шаблоне элемента управления. Я использую свой собственный шаблон пользовательского элемента управления для обоих элементов вкладки. Я использую разделитель в этом конкретном пространстве между этими элементами вкладки. Я даю красный цвет для подчеркивания этих заголовков вкладок элементов вкладки. И я также даю красный цвет для разделителя. И это также выглядит как анимированный индикатор вкладок.

Я могу использовать прямоугольник, но я не использую его, потому что разделитель более легкий.

Я знаю, что мне нужно использовать свойство раскадровки, чтобы убрать разделитель, но я не знаю, как его применить.

Я хочу, чтобы при переключении между этими двумя элементами вкладки разделитель переходил с одной стороны на другую и наоборот, чтобы было похоже, что красное подчеркивание перемещается с одного элемента вкладки на другой через пространство между ними

Вот шаблон элемента управления для элементов вкладки :

 <Style x:Key="TabItemGoTwo" TargetType="{x:Type TabItem}">
            <Setter Property="Foreground" Value="#939393" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Grid
                            x:Name="Root"
                            ClipToBounds="true"
                            KeyboardNavigation.TabNavigation="Local"
                            RenderOptions.BitmapScalingMode="NearestNeighbor"
                            RenderOptions.ClearTypeHint="Enabled"
                            SnapsToDevicePixels="true"
                            UseLayoutRounding="True">
                            <Border
                                x:Name="Border"
                                Margin="0,0,-4,0"
                                BorderThickness="1,1,1,1"
                                CornerRadius="2,12,0,0">
                                <Border.BorderBrush>
                                    <SolidColorBrush Color="#282828" />
                                </Border.BorderBrush>
                                <Border.Background>

                                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                        <LinearGradientBrush.GradientStops>
                                            <GradientStopCollection>
                                                <GradientStop Offset="0.0" Color="#282828" />
                                                <GradientStop Offset="1.0" Color="#282828" />
                                            </GradientStopCollection>
                                        </LinearGradientBrush.GradientStops>
                                    </LinearGradientBrush>

                                </Border.Background>
                                <ContentPresenter
                                    x:Name="ContentSite"
                                    Margin="0,2,12,2"
                                    HorizontalAlignment="Left"
                                    VerticalAlignment="Center"
                                    ContentSource="Header"
                                    RecognizesAccessKey="True"
                                    RenderOptions.BitmapScalingMode="NearestNeighbor"
                                    RenderOptions.ClearTypeHint="Enabled"
                                    SnapsToDevicePixels="True"
                                    UseLayoutRounding="True" />
                            </Border>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="HeaderTemplate">
                                    <Setter.Value>
                                        <DataTemplate>
                                            <StackPanel>
                                                <TextBlock
                                                    RenderOptions.EdgeMode="Aliased"
                                                    SnapsToDevicePixels="True"
                                                    Text="{TemplateBinding Content}"
                                                    UseLayoutRounding="True">

                                                    <TextBlock.TextDecorations>
                                                        <TextDecoration PenOffset="4" PenOffsetUnit="Pixel">
                                                            <TextDecoration.Pen>
                                                                <Pen Brush="#fe0000" Thickness="3" />
                                                            </TextDecoration.Pen>
                                                        </TextDecoration>
                                                    </TextBlock.TextDecorations>

                                                </TextBlock>
                                            </StackPanel>
                                        </DataTemplate>
                                    </Setter.Value>
                                </Setter>
                                <Setter Property="Foreground" Value="#fdfdfd" />
                                <Setter Property="Panel.ZIndex" Value="100" />
                            </Trigger>

                            <Trigger Property="IsSelected" Value="False">
                                <Setter TargetName="Root" Property="Background" Value="#282828" />
                            </Trigger>

                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Foreground" Value="#fdfdfd" />
                            </Trigger>

                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
  

Вот мой код для элементов вкладки, разделитель внутри этого элемента управления вкладкой.

 <StackPanel   Width="645" HorizontalAlignment="Left" Height="460" VerticalAlignment="Top" Margin="-4,59,0,0"    UseLayoutRounding="True" >
    <TabControl x:Name="MyTabControl" SelectionChanged="MyTabControl_SelectionChanged"    BorderThickness="0" Background="#282828"  Width="656" HorizontalAlignment="Left" Height="462" VerticalAlignment="Top" Margin="-5,1,-0.2,0"   >
        <TabItem  x:Name="TabItemFirst"    Style="{StaticResource TabItemGoTwo}"  Header="File manager"      Margin="34,0,-26.6,0" Height="24"                     FontSize="10" VerticalAlignment="Center"        UseLayoutRounding="True"  RenderOptions.ClearTypeHint="Enabled"  RenderOptions.BitmapScalingMode="NearestNeighbor"   SnapsToDevicePixels="True"  TextOptions.TextFormattingMode="Display"    FontFamily="Segoe UI"                  >
            <Grid   Background="#222222" Height="433" HorizontalAlignment="Left" VerticalAlignment="Top" Width="645" Margin="0,5,0,0"            >
                <Label Name="Folder" Content="Folder:"  FontSize="10" Foreground="#efefef"   Height="20" Width="40"  Margin="-571,-367,0,0"   FontFamily="Segoe UI" UseLayoutRounding="True" TextOptions.TextFormattingMode="Display"                                  />
                <Button Name ="FolderSelect"                               Width="532" HorizontalAlignment="Left" VerticalAlignment="Top"  Height="33" Margin="85,17,0,0"     Background="#1a1a1a"   
                                
                                materialDesign:ShadowAssist.ShadowDepth="Depth0" materialDesign:RippleAssist.Feedback="Transparent" BorderThickness="0"  UseLayoutRounding="True"
                                
                                ></Button>
                <Label Name="ShowFolders" Content=".." Margin="-479,59,0,0"  Background="#1a1a1a"  Width="168" Height="373"  Foreground="#efefef" ></Label>
                <Button
        Width="65" HorizontalAlignment="Left" Height="25" Background="#FF403D3D" Margin="16,292,0,0" 
        ToolTip="Resource name: MaterialDesignRaisedButton">
                    <materialDesign:PackIcon Kind="PlusThick" />
                </Button>
                <Button
        
        Width="65" HorizontalAlignment="Left" Height="25" Background="#FF403D3D" Margin="82,292,0,0" 
        ToolTip="Open output folder">
                    <materialDesign:PackIcon Kind="FolderUpload" />
                </Button>
                <Label Content="Video recordings:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="269.2,-22,0,0" Foreground="#efefef"  FontSize="10"  FontFamily="Segoe UI" UseLayoutRounding="True" TextOptions.TextFormattingMode="Display" />
            </Grid>
        </TabItem>
        <TabItem x:Name="TabItemSecond"  Style="{StaticResource  TabItemGoTwo}"  Header="Preview" FontSize="10" Height="24" Margin="47.4,0,-39.6,0"  FontFamily="Segoe UI"  VerticalAlignment="Center"    UseLayoutRounding="True"  RenderOptions.ClearTypeHint="Enabled"  RenderOptions.BitmapScalingMode="NearestNeighbor"   SnapsToDevicePixels="True" TextOptions.TextFormattingMode="Display"                                >
            <Grid></Grid>
        </TabItem>
    </TabControl>
</StackPanel>
<StackPanel   Height="10" Width="30"  Margin="-850,-395,0,0"                    >
    <Separator   Height="2" Background="#fe0000"   Margin="2,4,2.4,0"  SnapsToDevicePixels="True"  UseLayoutRounding="True"   RenderOptions.ClearTypeHint="Enabled"  RenderOptions.BitmapScalingMode="NearestNeighbor"     ></Separator>
</StackPanel>
  

Ответ №1:

Я заменяю ваш последний StackPanel на Canvas и обновляю ваш Separator с помощью приведенного ниже кода анимации:

 <Canvas>
        <Separator Height="2" Width="50" Background="Red"   Margin="25,82,4,0"   >
            <Separator.Style>
                <Style TargetType="Separator">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ElementName=MyTabControl,Path=SelectedIndex}" Value="1">
                            <DataTrigger.EnterActions>
                                <BeginStoryboard Name="MyBeginStoryboard">
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="0" To="100" Duration="0:0:1"></DoubleAnimation>
                                        <DoubleAnimation Storyboard.TargetProperty="Width" From="50" To="20" Duration="0:0:1"></DoubleAnimation>
                                    </Storyboard>
                                </BeginStoryboard>
                            </DataTrigger.EnterActions>
                            <DataTrigger.ExitActions>
                                <BeginStoryboard Name="MyBeginStoryboard2">
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" From="100" To="0" Duration="0:0:1"></DoubleAnimation>
                                        <DoubleAnimation Storyboard.TargetProperty="Width" From="30" To="50" Duration="0:0:1"></DoubleAnimation>
                                    </Storyboard>
                                </BeginStoryboard>
                            </DataTrigger.ExitActions>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Separator.Style>
        </Separator>
    </Canvas>