WPF窗体动态效果
阅读原文时间:2023年07月13日阅读:2

在浏览网页的时候,发现现在很多网页都采用这种效果。看起来很炫。

效果如下:

已经实现很久了,一直没写出来。今天突然想到,写出来分享一下

原理比较简单,就是在Window里面放一个MediaElement控件,播放视频就行

1、首先需要定义Window样式

如果使用 WindowStyle="None"属性再手动实现窗体效果,那窗体是没有阴影、标题栏,也没有动画效果,所以需要使用WindowChrome类来自定义窗体

WindowChrome类介绍https://docs.microsoft.com/zh-cn/dotnet/api/system.windows.shell.windowchrome?redirectedfrom=MSDN&view=netframework-4.8

一、新建一个WPF工程,命名为DynamicWindow

二、添加资源字典WindowStyle.xaml,用于自定义窗体样式

输入以下代码


 <Style x:Key="CaptionCloseButtonStyle" TargetType="{x:Type Button}">  
     <Setter Property="Focusable" Value="False" />  
     <Setter Property="Background" Value="Transparent" />  
     <Setter Property="BorderBrush" Value="Transparent" />  
     <Setter Property="BorderThickness"  Value="1" />  
     <Setter Property="HorizontalContentAlignment"   Value="Center" />  
     <Setter Property="VerticalContentAlignment"  Value="Center" />  
     <Setter Property="Template">  
         <Setter.Value>  
             <ControlTemplate TargetType="{x:Type Button}">  
                 <Grid x:Name="LayoutRoot">  
                     <Rectangle x:Name="TitleButtonBackground"  Width="40" Height="40" Fill="Silver" Opacity="0" />  
                     <Border x:Name="TitleButtonBorder" BorderBrush="{TemplateBinding BorderBrush}"  BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">  
                         <ContentPresenter x:Name="TitleButtonContent"  Focusable="False"  RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />  
                     </Border>  
                 </Grid>  
                 <ControlTemplate.Triggers>  
                     <Trigger Property="IsMouseOver" Value="true">  
                         <Setter Property="Background" Value="LightSkyBlue" TargetName="TitleButtonBorder" />  
                     </Trigger>  
                     <Trigger Property="IsPressed"  Value="True">  
                         <Setter Property="Opacity" Value="0.4"  TargetName="TitleButtonBackground" />  
                     </Trigger>  
                     <Trigger Property="IsEnabled"   Value="false">  
                         <Setter TargetName="TitleButtonContent"  Property="Opacity" Value=".5" />  
                     </Trigger>  
                 </ControlTemplate.Triggers>  
             </ControlTemplate>  
         </Setter.Value>  
     </Setter>  
 </Style>

 <DataTemplate x:Key="Minimize">  
     <Grid>  
         <Path Data="M 7.2 14.2 L19.2 14.2" Width="26.4"  Height="26.4" VerticalAlignment="Center"  HorizontalAlignment="Center"  Stroke="Black" StrokeThickness="1" />  
     </Grid>  
 </DataTemplate>

 <DataTemplate x:Key="Maximize">  
     <Grid>  
         <Rectangle Width="10" Height="10" Stroke="Black" StrokeThickness="1" Margin="0,1,0,0"/>  
     </Grid>  
 </DataTemplate>

 <DataTemplate x:Key="Restore">  
     <Grid>  
         <Rectangle Width="10" Height="10" Stroke="Black" StrokeThickness="1" Margin="0,3,3,0"/>  
         <Rectangle Width="8" Height="8" Stroke="Black" StrokeThickness="1" Margin="5,0,0,5"/>  
     </Grid>  
 </DataTemplate>

 <DataTemplate x:Key="Close">  
     <Grid Width="15.6" Height="15.4">  
         <Path Data="M 12,12 L16.4,16.4"  Stretch="Fill" Stroke="Black" StrokeThickness="1"/>  
         <Path Data="M 12,16.4 L 16.4,12 "  Stretch="Fill" Stroke="Black" StrokeThickness="1"/>  
     </Grid>  
 </DataTemplate>

 <Style TargetType="{x:Type Window}" x:Key="WindowStyle">  
     <Setter Property="BorderBrush"  Value="White" />  
     <Setter Property="BorderThickness"  Value="1" />  
     <Setter Property="ResizeMode"  Value="CanResizeWithGrip" />  
     <Setter Property="UseLayoutRounding" Value="True" />  
     <Setter Property="TextOptions.TextFormattingMode"  Value="Display" />  
     <Setter Property="WindowStyle" Value="SingleBorderWindow" />  
     <Setter Property="FontFamily" Value="LightSkyBlue" />  
     <Setter Property="WindowChrome.WindowChrome">  
         <Setter.Value>  
             <WindowChrome CornerRadius="0"  GlassFrameThickness="1" UseAeroCaptionButtons="False" NonClientFrameEdges="None" />  
         </Setter.Value>  
     </Setter>  
     <Setter Property="Template">  
         <Setter.Value>  
             <ControlTemplate TargetType="{x:Type Window}">  
                 <Border BorderBrush="{TemplateBinding BorderBrush}"  BorderThickness="{TemplateBinding BorderThickness}" x:Name="WindowBorder" Background="{TemplateBinding Background}">  
                     <!-- Background="{TemplateBinding Background}"-->  
                     <!--<Border.Background>  
                         <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">  
                             <GradientStop Color="#FFFFF9F9" Offset="0"/>  
                             <GradientStop Color="#FFA49B96" Offset="1"/>  
                         </LinearGradientBrush>  
                     </Border.Background>-->

                     <Grid x:Name="LayoutRoot">  
                         <Grid.RowDefinitions>  
                             <RowDefinition Height="26.4" />  
                             <RowDefinition />  
                         </Grid.RowDefinitions>

                         <Grid x:Name="PART\_WindowTitleGrid"  Grid.Row="0" Background="Transparent" Panel.ZIndex="1">  
                             <Grid.ColumnDefinitions>  
                                 <ColumnDefinition Width="\*" />  
                                 <ColumnDefinition Width="Auto" />  
                             </Grid.ColumnDefinitions>  
                             <StackPanel Orientation="Horizontal">  
                                 <Button VerticalAlignment="Center" Margin="7,0,5,0"  Height="{x:Static SystemParameters.SmallIconHeight}" Width="{x:Static SystemParameters.SmallIconWidth}" WindowChrome.IsHitTestVisibleInChrome="True"  
                                 IsTabStop="False" Command="{Binding Source={x:Static SystemCommands.ShowSystemMenuCommand}}" >  
                                     <Button.Template>  
                                         <ControlTemplate>  
                                             <!--title image-->  
                                             <Image Name="btnbg" HorizontalAlignment="Center" VerticalAlignment="Center"  Stretch="UniformToFill" Source="caption.png" Width="26.4" Height="26.4"/>  
                                         </ControlTemplate>  
                                     </Button.Template>  
                                 </Button>  
                                 <ContentControl IsTabStop="False"  
                                                 Foreground="LightSkyBlue"  
                                                 FontWeight="Bold"  
                                                 HorizontalAlignment="Center"  
                                                 VerticalAlignment="Center"  
                                                 FontSize="{DynamicResource {x:Static SystemFonts.CaptionFontSize}}"  
                                                 Content="{TemplateBinding Title}"  Margin="5,0,0,0"/>  
                             </StackPanel>  
                             <StackPanel x:Name="WindowCommandButtonsStackPanel"  Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Top" Orientation="Horizontal" WindowChrome.IsHitTestVisibleInChrome="True">  
                                 <Button x:Name="Minimize" Width="26.4" Height="26.4" ToolTip="最小化"  WindowChrome.IsHitTestVisibleInChrome="True"  Command="{Binding Source={x:Static SystemCommands.MinimizeWindowCommand}}"  ContentTemplate="{StaticResource Minimize}"  Style="{StaticResource CaptionNormalButtonStyle}"  IsTabStop="False" Margin="0,0,2,0"></Button>  
                                 <Button x:Name="Restore" Width="26.4" Height="26.4" ToolTip="还原" WindowChrome.IsHitTestVisibleInChrome="True"  Command="{Binding Source={x:Static SystemCommands.RestoreWindowCommand}}"   Visibility="Collapsed" ContentTemplate="{StaticResource Restore}" Style="{StaticResource CaptionNormalButtonStyle}" IsTabStop="False"></Button>  
                                 <Button x:Name="Maximize"  Width="26.4" Height="26.4" ToolTip="最大化" WindowChrome.IsHitTestVisibleInChrome="True" Command="{Binding Source={x:Static SystemCommands.MaximizeWindowCommand}}"   ContentTemplate="{StaticResource Maximize}" Style="{StaticResource CaptionNormalButtonStyle}" Margin="0,0,1,0" IsTabStop="False"></Button>  
                                 <Button x:Name="Close" Width="26.4" Height="26.4" ToolTip="关闭"  WindowChrome.IsHitTestVisibleInChrome="True"  Command="{Binding Source={x:Static SystemCommands.CloseWindowCommand}}"   IsTabStop="False"  Style="{StaticResource CaptionCloseButtonStyle}"  ContentTemplate="{StaticResource Close}" ></Button>  
                             </StackPanel>  
                         </Grid>  
                         <AdornerDecorator Grid.Row="0" Grid.RowSpan="2" KeyboardNavigation.IsTabStop="False">  
                             <ContentPresenter/>  
                         </AdornerDecorator>

                         <Grid Grid.Row="0" Grid.RowSpan="2" Panel.ZIndex="-1">  
                             <Grid>

                                 <!--window background-->  
                                 <!--<Grid.Background>  
                                     <ImageBrush ImageSource="../timg.jpg"  Stretch="UniformToFill"/>  
                                 </Grid.Background>-->

                             </Grid>  
                         </Grid>  
                         <ResizeGrip x:Name="ResizeGrip"  HorizontalAlignment="Right" VerticalAlignment="Bottom" Grid.Row="1" IsTabStop="False" Visibility="Hidden" WindowChrome.ResizeGripDirection="BottomRight" />  
                     </Grid>  
                 </Border>

                 <ControlTemplate.Triggers>  
                     <Trigger Property="WindowState" Value="Maximized">  
                         <Setter TargetName="Maximize" Property="Visibility" Value="Collapsed" />  
                         <Setter TargetName="Restore" Property="Visibility" Value="Visible" />  
                         <Setter TargetName="LayoutRoot" Property="Margin"  Value="7" />  
                     </Trigger>  
                     <Trigger Property="WindowState" Value="Normal">  
                         <Setter TargetName="Maximize" Property="Visibility" Value="Visible" />  
                         <Setter TargetName="Restore" Property="Visibility" Value="Collapsed" />  
                     </Trigger>  
                     <Trigger Property="ResizeMode"  Value="NoResize">  
                         <Setter TargetName="Minimize" Property="Visibility" Value="Collapsed" />  
                         <Setter TargetName="Maximize" Property="Visibility" Value="Collapsed" />  
                         <Setter TargetName="Restore"  Property="Visibility" Value="Collapsed" />  
                     </Trigger>  
                     <MultiTrigger>  
                         <MultiTrigger.Conditions>  
                             <Condition Property="ResizeMode"  Value="CanResizeWithGrip" />  
                             <Condition Property="WindowState" Value="Normal" />  
                         </MultiTrigger.Conditions>  
                         <Setter TargetName="ResizeGrip" Property="Visibility" Value="Visible" />  
                     </MultiTrigger>  
                 </ControlTemplate.Triggers>  
             </ControlTemplate>  
         </Setter.Value>  
     </Setter>  
 </Style>  

2、引入资源字典

在App.xaml中输入以下代码

3、添加一个MediaElement控件

打开MainWindow.xaml,输入以下代码


     <Grid Grid.Row="1">  
         <Button Content="播放" HorizontalAlignment="Left" VerticalAlignment="Top" Click="Button\_Click"></Button>  
         <Button Content="停止" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="50,0,0,0" Click="Button\_Click\_1"></Button>  
     </Grid>  
 </Grid>  

4、运行,点击播放就可以看到效果

示例代码

2019.07.12