XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEToolBox

【WPF】XFE工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
<UserControl x:Class="XFEToolBox.WpfCore.Controls.Carousel"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:controls="clr-namespace:XFEToolBox.WpfCore.Controls"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d"
             d:DesignHeight="320" d:DesignWidth="900"
             Focusable="True"
             PreviewKeyDown="Carousel_PreviewKeyDown">
    <UserControl.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>

        <Style x:Key="CarouselNavigationButton" TargetType="Button">
            <Setter Property="Width" Value="40"/>
            <Setter Property="Height" Value="40"/>
            <Setter Property="Background" Value="#E8FFFFFF"/>
            <Setter Property="Foreground" Value="#666684"/>
            <Setter Property="BorderBrush" Value="#5CFFFFFF"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Cursor" Value="Hand"/>
            <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
            <Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
            <Setter Property="RenderTransform">
                <Setter.Value><ScaleTransform ScaleX="1" ScaleY="1"/></Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                CornerRadius="20">
                            <Border.Effect>
                                <DropShadowEffect Color="#343052" BlurRadius="15" ShadowDepth="3" Opacity="0.22"/>
                            </Border.Effect>
                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" Value="{DynamicResource MainColor}"/>
                                <Setter Property="Foreground" Value="White"/>
                                <Setter Property="BorderBrush" Value="#D9FFFFFF"/>
                                <Setter Property="RenderTransform">
                                    <Setter.Value><ScaleTransform ScaleX="1.08" ScaleY="1.08"/></Setter.Value>
                                </Setter>
                            </Trigger>
                            <Trigger Property="IsPressed" Value="True">
                                <Setter Property="RenderTransform">
                                    <Setter.Value><ScaleTransform ScaleX="0.94" ScaleY="0.94"/></Setter.Value>
                                </Setter>
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="False"><Setter Property="Opacity" Value="0.35"/></Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style x:Key="CarouselActionButton" TargetType="Button">
            <Setter Property="Height" Value="34"/>
            <Setter Property="Padding" Value="14,0"/>
            <Setter Property="Background" Value="#F2FFFFFF"/>
            <Setter Property="Foreground" Value="#565675"/>
            <Setter Property="BorderBrush" Value="#70FFFFFF"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Cursor" Value="Hand"/>
            <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
            <Setter Property="FontSize" Value="12"/>
            <Setter Property="FontWeight" Value="SemiBold"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Border Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                CornerRadius="17">
                            <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" Value="{DynamicResource MainColor}"/>
                                <Setter Property="Foreground" Value="White"/>
                            </Trigger>
                            <Trigger Property="IsPressed" Value="True"><Setter Property="Opacity" Value="0.78"/></Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </UserControl.Resources>

    <Grid Margin="3">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="28"/>
        </Grid.RowDefinitions>

        <Border x:Name="CardBorder"
                Grid.Row="0"
                Padding="3"
                Background="#F7F7FE"
                BorderBrush="#72FFFFFF"
                BorderThickness="1"
                CornerRadius="18">
            <Border.Effect>
                <DropShadowEffect Color="#4B4775" BlurRadius="18" ShadowDepth="5" Opacity="0.2"/>
            </Border.Effect>

            <controls:RoundedClipBorder Background="#252538" CornerRadius="15">
                <Grid x:Name="ImageViewport" ClipToBounds="True" SizeChanged="ImageViewport_SizeChanged">
                    <!-- 两层图片只用于过渡,切换时不会重新创建视觉树。 -->
                    <Image x:Name="ImageBack"
                           Stretch="UniformToFill"
                           Opacity="0"
                           MouseLeftButtonUp="Image_MouseLeftButtonUp"/>
                    <Image x:Name="ImageFront"
                           Stretch="UniformToFill"
                           Opacity="1"
                           MouseLeftButtonUp="Image_MouseLeftButtonUp"/>

                    <Border Height="118" VerticalAlignment="Bottom" IsHitTestVisible="False">
                        <Border.Background>
                            <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                                <GradientStop Color="#00191830" Offset="0"/>
                                <GradientStop Color="#C91B1A32" Offset="0.62"/>
                                <GradientStop Color="#F21B1A32" Offset="1"/>
                            </LinearGradientBrush>
                        </Border.Background>
                    </Border>

                    <Grid Margin="22,0,22,18"
                          VerticalAlignment="Bottom"
                          Visibility="{Binding HasItems, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource BooleanToVisibilityConverter}}">
                        <StackPanel VerticalAlignment="Bottom">
                            <Border MinWidth="74" Height="23" Padding="12,0" HorizontalAlignment="Left" Margin="0,0,0,7"
                                    Background="#389898E7" BorderBrush="#66FFFFFF" BorderThickness="1" CornerRadius="11.5">
                                <TextBlock Text="{Binding CurrentBadge, RelativeSource={RelativeSource AncestorType=UserControl}}" Foreground="#F2FFFFFF" FontSize="10.5"
                                           FontWeight="SemiBold" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                            </Border>
                            <TextBlock Text="{Binding CurrentTitle, RelativeSource={RelativeSource AncestorType=UserControl}}"
                                       Foreground="White" FontSize="17" FontWeight="SemiBold"
                                       TextTrimming="CharacterEllipsis" VerticalAlignment="Center"/>
                        </StackPanel>
                    </Grid>

                    <Button Margin="15,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center"
                            Style="{StaticResource CarouselNavigationButton}"
                            Visibility="{Binding HasMultipleItems, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource BooleanToVisibilityConverter}}"
                            Click="PrevButton_Click" ToolTip="上一张" AutomationProperties.Name="上一张轮播图">
                        <Path Width="15" Height="15" Data="M 10.5,2 L 4.5,7.5 L 10.5,13"
                              Stroke="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}"
                              StrokeThickness="2" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round"/>
                    </Button>

                    <Button Margin="0,0,15,0" HorizontalAlignment="Right" VerticalAlignment="Center"
                            Style="{StaticResource CarouselNavigationButton}"
                            Visibility="{Binding HasMultipleItems, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource BooleanToVisibilityConverter}}"
                            Click="NextButton_Click" ToolTip="下一张" AutomationProperties.Name="下一张轮播图">
                        <Path Width="15" Height="15" Data="M 4.5,2 L 10.5,7.5 L 4.5,13"
                              Stroke="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}"
                              StrokeThickness="2" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round"/>
                    </Button>

                    <Border Background="#FFF8F8FE"
                            Visibility="{Binding IsLoading, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource BooleanToVisibilityConverter}}">
                        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                            <ProgressBar Width="150" Height="4" IsIndeterminate="True" Foreground="{DynamicResource MainColor}" Background="#E8E8F5"/>
                            <TextBlock Margin="0,14,0,0" Text="{Binding StatusMessage, RelativeSource={RelativeSource AncestorType=UserControl}}"
                                       Foreground="#77778E" FontSize="12" HorizontalAlignment="Center"/>
                        </StackPanel>
                    </Border>

                    <Border Background="#FFF8F8FE">
                        <Border.Style>
                            <Style TargetType="Border">
                                <Setter Property="Visibility" Value="Collapsed"/>
                                <Style.Triggers>
                                    <MultiDataTrigger>
                                        <MultiDataTrigger.Conditions>
                                            <Condition Binding="{Binding HasItems, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="False"/>
                                            <Condition Binding="{Binding IsLoading, RelativeSource={RelativeSource AncestorType=UserControl}}" Value="False"/>
                                        </MultiDataTrigger.Conditions>
                                        <Setter Property="Visibility" Value="Visible"/>
                                    </MultiDataTrigger>
                                </Style.Triggers>
                            </Style>
                        </Border.Style>
                        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
                            <Border Width="52" Height="52" Background="#EDEDFB" CornerRadius="17">
                                <Path Width="25" Height="25" Stretch="Uniform" Fill="{DynamicResource MainColor}"
                                      Data="M 2,4 C 2,2.9 2.9,2 4,2 L 20,2 C 21.1,2 22,2.9 22,4 L 22,17 C 22,18.1 21.1,19 20,19 L 4,19 C 2.9,19 2,18.1 2,17 Z M 4,15 L 9,10 L 12.5,13.5 L 15,11 L 20,16 L 20,4 L 4,4 Z M 16.5,6 C 17.3,6 18,6.7 18,7.5 C 18,8.3 17.3,9 16.5,9 C 15.7,9 15,8.3 15,7.5 C 15,6.7 15.7,6 16.5,6 Z"/>
                            </Border>
                            <TextBlock Margin="0,13,0,0" Text="暂时没有可展示的内容" Foreground="#4D4D65"
                                       FontSize="14" FontWeight="SemiBold" HorizontalAlignment="Center"/>
                            <TextBlock Margin="0,5,0,0" Text="{Binding StatusMessage, RelativeSource={RelativeSource AncestorType=UserControl}}"
                                       Foreground="#9292A5" FontSize="11" HorizontalAlignment="Center"/>
                            <Button Margin="0,14,0,0" Height="32" Padding="16,0"
                                    Content="重新加载" Style="{StaticResource CarouselActionButton}"
                                    Visibility="{Binding CanRetry, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource BooleanToVisibilityConverter}}"
                                    Click="RetryButton_Click"/>
                        </StackPanel>
                    </Border>
                </Grid>
            </controls:RoundedClipBorder>
        </Border>

        <!-- 分页指示器保留历史独立样式,不继承普通操作按钮模板。 -->
        <Grid Grid.Row="1" Background="Transparent" Margin="0,8,0,0">
            <ItemsControl ItemsSource="{Binding ImageList, RelativeSource={RelativeSource AncestorType=UserControl}}"
                          HorizontalAlignment="Center" VerticalAlignment="Center"
                          Visibility="{Binding HasMultipleItems, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource BooleanToVisibilityConverter}}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Border Background="Transparent" Padding="6" Cursor="Hand"
                                MouseLeftButtonUp="Indicator_MouseLeftButtonUp" ToolTip="切换到此项">
                            <Grid>
                                <Ellipse x:Name="Dot" Width="5" Height="5" Opacity="0.5" RenderTransformOrigin="0.5,0.5">
                                    <Ellipse.Fill>
                                        <SolidColorBrush Color="#FFFFFF"/>
                                    </Ellipse.Fill>
                                    <Ellipse.RenderTransform>
                                        <ScaleTransform ScaleX="1" ScaleY="1"/>
                                    </Ellipse.RenderTransform>
                                </Ellipse>
                            </Grid>
                        </Border>
                        <DataTemplate.Triggers>
                            <DataTrigger Binding="{Binding IsSelected}" Value="True">
                                <DataTrigger.EnterActions>
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <ColorAnimation Storyboard.TargetName="Dot" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="#FF6A5ACD" Duration="0:0:0.12"/>
                                            <DoubleAnimation Storyboard.TargetName="Dot" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.12"/>
                                            <DoubleAnimation Storyboard.TargetName="Dot" Storyboard.TargetProperty="RenderTransform.(ScaleTransform.ScaleX)" To="1.4" Duration="0:0:0.18"/>
                                            <DoubleAnimation Storyboard.TargetName="Dot" Storyboard.TargetProperty="RenderTransform.(ScaleTransform.ScaleY)" To="1.4" Duration="0:0:0.18"/>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </DataTrigger.EnterActions>
                                <DataTrigger.ExitActions>
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <ColorAnimation Storyboard.TargetName="Dot" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" To="#FFFFFF" Duration="0:0:0.12"/>
                                            <DoubleAnimation Storyboard.TargetName="Dot" Storyboard.TargetProperty="Opacity" To="0.5" Duration="0:0:0.12"/>
                                            <DoubleAnimation Storyboard.TargetName="Dot" Storyboard.TargetProperty="RenderTransform.(ScaleTransform.ScaleX)" To="1" Duration="0:0:0.18"/>
                                            <DoubleAnimation Storyboard.TargetName="Dot" Storyboard.TargetProperty="RenderTransform.(ScaleTransform.ScaleY)" To="1" Duration="0:0:0.18"/>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </DataTrigger.ExitActions>
                            </DataTrigger>
                        </DataTemplate.Triggers>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Grid>
    </Grid>
</UserControl>