WPF进阶 | WPF 动画特效揭秘:实现炫酷的界面交互效果
WPF进阶 | WPF 动画特效揭秘:实现炫酷的界面交互效果
- 前言
- 一、WPF 动画基础概念
- 1.1 什么是 WPF 动画
- 1.2 动画的基本类型
- 1.3 动画的核心元素
- 二、线性动画详解
- 2.1 DoubleAnimation 的使用
- 2.2 ColorAnimation 实现颜色渐变
- 三、关键帧动画深入
- 3.1 DoubleAnimationUsingKeyFrames 创建复杂动画
- 3.2 ColorAnimationUsingKeyFrames 实现多色渐变
- 四、路径动画探索
- 4.1 PointAnimationUsingPath 实现沿路径移动
- 4.2 PathAnimation 实现复杂路径动画
- 五、动画的高级应用与技巧
- 5.1 缓动函数(Easing Functions)
- 5.2 动画组(Animation Groups)
- 5.3 动画事件(Animation Events)
- 六、实际应用案例
- 6.1 打造欢迎界面动画
- 6.2 实现动态菜单交互效果
- 七、性能优化与注意事项
- 7.1 性能优化
- 7.2 注意事项
- 八、总结
- 结束语
- 优质源码分享
WPF进阶 | WPF 动画特效揭秘:实现炫酷的界面交互效果
,在当今竞争激烈的软件市场中,用户界面的交互体验至关重要。一个拥有炫酷动画特效的应用程序,不仅能吸引用户的注意力,还能显著提升用户与界面的交互流畅度和愉悦感。Windows Presentation Foundation(WPF)作为微软强大的桌面应用程序开发框架,提供了丰富且强大的动画功能,使开发者能够轻松创建出各种令人惊叹的动画特效,实现出色的界面交互效果。本文将深入剖析 WPF 动画特效的各个方面,通过大量详细的代码示例和对关键概念的深入解释,帮助读者全面掌握这一强大的工具,为打造独特且吸引人的用户界面奠定坚实基础。
前言
在数字浪潮汹涌澎湃的时代,程序开发宛如一座神秘而宏伟的魔法城堡,矗立在科技的浩瀚星空中。代码的字符,似那闪烁的星辰,按照特定的轨迹与节奏,组合、交织、碰撞,即将开启一场奇妙且充满无限可能的创造之旅。当空白的文档界面如同深邃的宇宙等待探索,程序员们则化身无畏的星辰开拓者,指尖在键盘上轻舞,准备用智慧与逻辑编织出足以改变世界运行规则的程序画卷,在 0 和 1 的二进制世界里,镌刻下属于人类创新与突破的不朽印记。
在当今数字化时代,桌面应用程序的用户界面(UI)设计至关重要,它直接影响着用户体验与产品的竞争力。而 WPF(Windows Presentation Foundation)作为微软推出的一款强大的 UI 框架,其布局系统更是构建精美界面的核心要素。WPF 布局系统为开发者提供了丰富多样的布局方式,能够轻松应对各种复杂的界面设计需求,无论是简洁明了的工具软件,还是功能繁杂的企业级应用,都能借助其打造出令人惊艳的视觉效果与流畅的交互体验。
WPF从入门到精通专栏,旨在为读者呈现一条从对 WPF(Windows Presentation Foundation)技术懵懂无知到精通掌握的学习路径。首先从基础入手,介绍 WPF 的核心概念,涵盖其独特的架构特点、开发环境搭建流程,详细解读布局系统、常用控件以及事件机制等基础知识,帮助初学者搭建起对 WPF 整体的初步认知框架。随着学习的深入,进阶部分聚焦于数据绑定、样式模板、动画特效等关键知识点,进一步拓展 WPF 开发的能力边界,使开发者能够打造出更为个性化、交互性强的桌面应用界面。高级阶段则涉及自定义控件开发、MVVM 设计模式应用、多线程编程等深层次内容,助力开发者应对复杂的业务需求,构建大型且可维护的应用架构。同时,通过实战项目案例解析,展示如何将所学知识综合运用到实际开发中,从需求分析到功能实现再到优化测试,全方位积累实践经验。此外,还探讨了性能优化、与其他技术集成以及安全机制等拓展性话题,让读者对 WPF 技术在不同维度有更深入理解,最终实现对 WPF 技术的精通掌握,具备独立开发高质量桌面应用的能力。
🛕 点击进入WPF从入门到精通专栏
一、WPF 动画基础概念
1.1 什么是 WPF 动画
WPF 动画是一种通过随时间改变对象属性值来创建动态视觉效果的技术。与传统的基于帧的动画不同,WPF 动画基于属性驱动,这意味着开发者只需指定动画的起始值、结束值以及持续时间等关键参数,WPF 框架会自动计算并在指定时间内平滑地改变对象的属性值,从而实现动画效果。例如,我们可以通过动画让一个按钮在点击时逐渐放大,或者让一个文本框的背景颜色在一段时间内渐变。
1.2 动画的基本类型
- WPF 主要提供了三种类型的动画:
线性动画(Linear Animations):这类动画以恒定的速度改变属性值,从起始值线性过渡到结束值。例如,DoubleAnimation
用于对double类型的属性进行线性动画,如改变控件的宽度、高度或透明度等。
关键帧动画(Key - Frame Animations):关键帧动画允许在动画过程中定义多个关键时间点及其对应的属性值,动画会在这些关键帧之间进行插值计算,从而实现更复杂的动画效果。例如,DoubleAnimationUsingKeyFrames
可以定义多个不同时间点的double
值,使控件的属性按照这些关键帧的值进行变化。
路径动画(Path Animations):路径动画用于使对象沿着指定的路径移动。通过PathGeometry
定义路径,然后使用PointAnimationUsingPath
等动画类型,让对象能够沿着复杂的路径进行运动,这在创建一些具有特定轨迹的动画效果时非常有用。
1.3 动画的核心元素
在 WPF 中,创建动画主要涉及以下几个核心元素:
动画类(Animation Classes):如前面提到的DoubleAnimation
、DoubleAnimationUsingKeyFrames
等,这些类继承自Timeline类,负责定义动画的具体行为,包括起始值、结束值、持续时间、缓动函数等。
故事板(Storyboard):Storyboard
是一个用于管理和控制一组动画的容器。它可以包含多个动画,并且可以通过Begin
、Stop
、Pause
等方法来控制动画的播放。例如,我们可以在一个Storyboard
中同时包含按钮的放大动画和颜色渐变动画,使按钮在点击时同时产生多种动画效果。
依赖属性(Dependency Properties):动画是通过改变对象的依赖属性来实现的。依赖属性是 WPF 中一种特殊的属性类型,它具有很多优点,如支持数据绑定、样式设置、动画等。几乎所有 WPF 控件的可视属性,如Width
、Height
、Opacity
等,都是依赖属性,这使得它们能够方便地参与动画过程。
二、线性动画详解
2.1 DoubleAnimation 的使用
DoubleAnimation
是最常用的线性动画之一,用于对double
类型的属性进行动画操作。下面是一个简单的示例,展示如何使用DoubleAnimation
让一个按钮在点击时逐渐放大:
<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="DoubleAnimation Example" Height="350" Width="525"><Window.Resources><Storyboard x:Key="ButtonGrowStoryboard"><DoubleAnimationStoryboard.TargetName="MyButton"Storyboard.TargetProperty="Width"From="100" To="150" Duration="0:0:0.5"/></Storyboard></Window.Resources><Grid><Button x:Name="MyButton" Content="Click Me" HorizontalAlignment="Center" VerticalAlignment="Center"Click="MyButton_Click"><Button.Triggers><EventTrigger RoutedEvent="Button.Click"><BeginStoryboard Storyboard="{StaticResource ButtonGrowStoryboard}"/></EventTrigger></Button.Triggers></Button></Grid>
</Window>
在上述代码中:
首先在Window.Resources
中定义了一个Storyboard
,其中包含一个DoubleAnimation
。Storyboard.TargetName
指定了动画作用的目标控件为MyButton
,Storyboard.TargetProperty
指定了要动画的属性为Width
。From
属性指定了动画的起始值为100,To属性指定了结束值为150,Duration
属性指定了动画持续时间为 0.5 秒。
在Button
控件中,通过EventTrigger
监听按钮的Click事件,当按钮被点击时,触发BeginStoryboard
,从而启动ButtonGrowStoryboard
动画,使按钮的宽度从 100 逐渐增加到 150。
2.2 ColorAnimation 实现颜色渐变
ColorAnimation用于对颜色属性进行动画操作,实现颜色的渐变效果。例如,我们可以让一个矩形的填充颜色在一段时间内从红色渐变为蓝色:
<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="ColorAnimation Example" Height="350" Width="525"><Window.Resources><Storyboard x:Key="RectangleColorStoryboard"><ColorAnimationStoryboard.TargetName="MyRectangle"Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)"From="Red" To="Blue" Duration="0:0:2"/></Storyboard></Window.Resources><Grid><Rectangle x:Name="MyRectangle" Width="200" Height="100" Fill="Red" HorizontalAlignment="Center" VerticalAlignment="Center"><Rectangle.Triggers><EventTrigger RoutedEvent="Rectangle.MouseEnter"><BeginStoryboard Storyboard="{StaticResource RectangleColorStoryboard}"/></EventTrigger></Rectangle.Triggers></Rectangle></Grid>
</Window>
这里:
Storyboard
中的ColorAnimation
将MyRectangle
的填充颜色从红色渐变为蓝色。Storyboard.TargetProperty
使用了一种较为复杂的语法,因为Rectangle
的Fill
属性是一个Brush
,而我们要动画的是Brush
的Color
属性,所以使用(Rectangle.Fill).(SolidColorBrush.Color)
来指定。
当鼠标进入矩形时,通过EventTrigger
触发动画,实现颜色渐变效果。
三、关键帧动画深入
3.1 DoubleAnimationUsingKeyFrames 创建复杂动画
DoubleAnimationUsingKeyFrames
允许通过定义多个关键帧来创建复杂的动画效果。每个关键帧都有一个时间点和对应的属性值。例如,我们可以创建一个让按钮的宽度按照不同的速度和时间进行变化的动画:
<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="DoubleAnimationUsingKeyFrames Example" Height="350" Width="525"><Window.Resources><Storyboard x:Key="ButtonComplexGrowStoryboard"><DoubleAnimationUsingKeyFramesStoryboard.TargetName="MyButton"Storyboard.TargetProperty="Width"><EasingDoubleKeyFrame Value="100" KeyTime="0:0:0"/><EasingDoubleKeyFrame Value="120" KeyTime="0:0:0.3" EasingFunction="{StaticResource CubicEaseOut}"/><EasingDoubleKeyFrame Value="150" KeyTime="0:0:0.6" EasingFunction="{StaticResource QuadraticEaseOut}"/></DoubleAnimationUsingKeyFrames></Storyboard><CubicEase x:Key="CubicEaseOut" EasingMode="EaseOut"/><QuadraticEase x:Key="QuadraticEaseOut" EasingMode="EaseOut"/></Window.Resources><Grid><Button x:Name="MyButton" Content="Click Me" HorizontalAlignment="Center" VerticalAlignment="Center"Click="MyButton_Click"><Button.Triggers><EventTrigger RoutedEvent="Button.Click"><BeginStoryboard Storyboard="{StaticResource ButtonComplexGrowStoryboard}"/></EventTrigger></Button.Triggers></Button></Grid>
</Window>
在这个例子中:
定义了三个关键帧。第一个关键帧在动画开始时(KeyTime="0:0:0"
),按钮宽度为100。第二个关键帧在 0.3 秒时,按钮宽度变为120,并使用了CubicEaseOut
缓动函数,使动画在接近该关键帧时减速。第三个关键帧在 0.6 秒时,按钮宽度变为150,使用QuadraticEaseOut
缓动函数。
通过这种方式,可以创建出比简单线性动画更丰富、更自然的动画效果。
3.2 ColorAnimationUsingKeyFrames 实现多色渐变
ColorAnimationUsingKeyFrames用于创建颜色的多色渐变动画。比如,我们可以让一个椭圆的填充颜色在不同时间点依次变为红、绿、蓝:
<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="ColorAnimationUsingKeyFrames Example" Height="350" Width="525"><Window.Resources><Storyboard x:Key="EllipseColorStoryboard"><ColorAnimationUsingKeyFramesStoryboard.TargetName="MyEllipse"Storyboard.TargetProperty="(Ellipse.Fill).(SolidColorBrush.Color)"><EasingColorKeyFrame Value="Red" KeyTime="0:0:0"/><EasingColorKeyFrame Value="Green" KeyTime="0:0:1"/><EasingColorKeyFrame Value="Blue" KeyTime="0:0:2"/></ColorAnimationUsingKeyFrames></Storyboard></Window.Resources><Grid><Ellipse x:Name="MyEllipse" Width="100" Height="100" Fill="Red" HorizontalAlignment="Center" VerticalAlignment="Center"><Ellipse.Triggers><EventTrigger RoutedEvent="Ellipse.MouseEnter"><BeginStoryboard Storyboard="{StaticResource EllipseColorStoryboard}"/></EventTrigger></Ellipse.Triggers></Ellipse></Grid>
</Window>
此代码中:
定义了三个关键帧,分别在动画开始、1 秒和 2 秒时将椭圆的填充颜色设置为红、绿、蓝。当鼠标进入椭圆时,触发该动画,实现颜色的多色渐变效果。
四、路径动画探索
4.1 PointAnimationUsingPath 实现沿路径移动
PointAnimationUsingPath
用于使对象沿着指定的路径移动。下面是一个简单的示例,让一个圆形沿着一个椭圆路径移动:
<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="PointAnimationUsingPath Example" Height="350" Width="525"><Window.Resources><Storyboard x:Key="CircleMoveStoryboard"><PointAnimationUsingPathStoryboard.TargetName="MyCircle"Storyboard.TargetProperty="(Canvas.Left, Canvas.Top)"PathGeometry="{StaticResource EllipsePath}"Duration="0:0:5" RepeatBehavior="Forever"/></Storyboard><PathGeometry x:Key="EllipsePath"><PathFigure StartPoint="100,100"><ArcSegment Point="300,100" Size="100,50" IsLargeArc="True" SweepDirection="Counterclockwise"/></PathFigure></PathGeometry></Window.Resources><Canvas><Ellipse x:Name="MyCircle" Width="20" Height="20" Fill="Red" Canvas.Left="100" Canvas.Top="100"><Ellipse.Triggers><EventTrigger RoutedEvent="Ellipse.Loaded"><BeginStoryboard Storyboard="{StaticResource CircleMoveStoryboard}"/></EventTrigger></Ellipse.Triggers></Ellipse></Canvas>
</Window>
在这段代码中:
首先定义了一个PathGeometry
,它描述了一个椭圆路径。PathFigure
指定了路径的起始点,ArcSegment
定义了椭圆弧的终点、大小、是否为大弧以及扫描方向。
PointAnimationUsingPath
的Storyboard.TargetProperty
指定为(Canvas.Left, Canvas.Top
),表示要同时动画圆形的Canvas.Lef
t和Canvas.Top
属性,使其沿着指定的椭圆路径移动。Duration
设置为 5 秒,RepeatBehavior
设置为Forever
,表示动画将无限循环。
当椭圆加载完成时,触发动画,圆形开始沿着椭圆路径移动。
4.2 PathAnimation 实现复杂路径动画
PathAnimation可以用于对更复杂的路径相关属性进行动画。例如,我们可以让一个路径的笔画宽度沿着路径的长度进行变化:
<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="PathAnimation Example" Height="350" Width="525"><Window.Resources><Storyboard x:Key="PathStrokeWidthStoryboard"><PathAnimationStoryboard.TargetName="MyPath"Storyboard.TargetProperty="StrokeThickness"PathGeometry="{StaticResource ComplexPath}"Duration="0:0:3"><PathAnimation.KeyFrames><LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/><LinearDoubleKeyFrame Value="5" KeyTime="0:0:1.5"/><LinearDoubleKeyFrame Value="1" KeyTime="0:0:3"/></PathAnimation.KeyFrames></PathAnimation></Storyboard><PathGeometry x:Key="ComplexPath"><PathFigure StartPoint="50,50"><LineSegment Point="150,150"/><ArcSegment Point="250,50" Size="50,50" IsLargeArc="True" SweepDirection="Clockwise"/></PathFigure></PathGeometry></Window.Resources><Canvas><Path x:Name="MyPath" Stroke="Blue" StrokeThickness="1" Data="{StaticResource ComplexPath}"><Path.Triggers><EventTrigger RoutedEvent="Path.Loaded"><BeginStoryboard Storyboard="{StaticResource PathStrokeWidthStoryboard}"/></EventTrigger></Path.Triggers></Path></Canvas>
</Window>
这里:
定义了一个复杂的PathGeometry
,包含直线段和弧线。PathAnimation
用于对Path
的StrokeThickness
属性进行动画。
通过KeyFrames
定义了三个关键帧,使笔画宽度在动画开始时为 1,1.5 秒时变为 5,3 秒时又变回 1。当路径加载完成时,动画开始,实现路径笔画宽度的动态变化。
五、动画的高级应用与技巧
5.1 缓动函数(Easing Functions)
缓动函数是 WPF 动画中非常重要的一部分,它能够改变动画的速度曲线,使动画效果更加自然和生动。在前面的关键帧动画示例中,我们已经简单使用了CubicEaseOut
和QuadraticEaseOut
等缓动函数。
WPF 提供了多种内置的缓动函数,如LinearEase
(线性缓动,动画以恒定速度进行)、BackEase
(模拟物体向后退再向前的效果)、BounceEase
(实现类似物体弹跳的效果)、ElasticEase
(模拟弹性物体的运动效果)等。每种缓动函数都有其独特的动画表现,通过设置EasingMode
属性,还可以控制缓动的方向,如EaseIn
(动画开始时缓慢,逐渐加速)、EaseOut
(动画开始时快速,逐渐减速)、EaseInOut
(动画开始和结束时缓慢,中间快速)。
以BounceEase为例,我们可以让一个按钮在点击时产生弹跳效果:
<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="BounceEase Example" Height="350" Width="525"><Window.Resources><Storyboard x:Key="ButtonBounceStoryboard"><DoubleAnimationStoryboard.TargetName="MyButton"Storyboard.TargetProperty="Height"From="100" To="150" Duration="0:0:1"><DoubleAnimation.EasingFunction><BounceEase Bounces="3" EasingMode="EaseOut"/></DoubleAnimation.EasingFunction></DoubleAnimation></Storyboard></Window.Resources><Grid><Button x:Name="MyButton" Content="Click Me" HorizontalAlignment="Center" VerticalAlignment="Center"Click="MyButton_Click"><Button.Triggers><EventTrigger RoutedEvent="Button.Click"><BeginStoryboard Storyboard="{StaticResource ButtonBounceStoryboard}"/></EventTrigger></Button.Triggers></Button></Grid>
</Window>
在这个例子中,BounceEase
的Bounces
属性设置为 3,表示按钮在动画结束时会弹跳 3 次,EasingMode
为EaseOut
,意味着动画在结束阶段产生弹跳效果。
5.2 动画组(Animation Groups)
动画组允许在一个Storyboard
中同时运行多个动画,并且可以控制它们之间的时间关系。例如,我们可以让一个图像在放大的同时旋转,创建出更丰富的动画效果。
<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="Animation Group Example" Height="350" Width="525"><Window.Resources><Storyboard x:Key="ImageAnimationStoryboard"><DoubleAnimationStoryboard.TargetName="MyImage"Storyboard.TargetProperty="Width"From="100" To="150" Duration="0:0:1"/><DoubleAnimationStoryboard.TargetName="MyImage"Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"From="0" To="360" Duration="0:0:1"/></Storyboard><RotateTransform x:Key="ImageRotateTransform" Angle="0"/></Window.Resources><Grid><Image x:Name="MyImage" Source="yourImage.jpg" HorizontalAlignment="Center" VerticalAlignment="Center"><Image.RenderTransform><RotateTransform x:Name="ImageRotateTransform" Angle="0"/></Image.RenderTransform><Image.Triggers><EventTrigger RoutedEvent="Image.MouseEnter"><BeginStoryboard Storyboard="{StaticResource ImageAnimationStoryboard}"/></EventTrigger></Image.Triggers></Image></Grid>
</Window>
在这段代码中,Storyboard
包含了两个动画:一个是DoubleAnimation
用于放大图像的宽度,另一个也是DoubleAnimation
用于旋转图像。通过这种方式,当鼠标进入图像时,图像会同时进行放大和旋转动画。
5.3 动画事件(Animation Events)
动画事件允许开发者在动画的特定阶段执行自定义代码,比如动画开始、结束或重复时。以Storyboard
的Completed
事件为例,我们可以在一个动画结束后执行一些操作,如显示一个提示信息。
<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="Animation Events Example" Height="350" Width="525"><Window.Resources><Storyboard x:Key="ButtonFadeOutStoryboard" Completed="ButtonFadeOutStoryboard_Completed"><DoubleAnimationStoryboard.TargetName="MyButton"Storyboard.TargetProperty="Opacity"From="1" To="0" Duration="0:0:1"/></Storyboard></Window.Resources><Grid><Button x:Name="MyButton" Content="Click Me" HorizontalAlignment="Center" VerticalAlignment="Center"Click="MyButton_Click"><Button.Triggers><EventTrigger RoutedEvent="Button.Click"><BeginStoryboard Storyboard="{StaticResource ButtonFadeOutStoryboard}"/></EventTrigger></Button.Triggers></Button></Grid>
</Window>
在后台代码中:
using System.Windows;namespace WpfApp1
{public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}private void MyButton_Click(object sender, RoutedEventArgs e){// 按钮点击逻辑}private void ButtonFadeOutStoryboard_Completed(object sender, System.EventArgs e){MessageBox.Show("按钮已消失");}}
}
当ButtonFadeOutStoryboard
动画结束时,会触发Completed
事件,执行ButtonFadeOutStoryboard_Completed
方法,弹出一个提示框。
六、实际应用案例
6.1 打造欢迎界面动画
在很多应用程序中,欢迎界面往往会使用动画来吸引用户的注意力。我们可以使用 WPF 动画创建一个简单而炫酷的欢迎界面。例如,让应用程序的图标逐渐放大并旋转,同时显示一段欢迎文字,文字从透明渐变到不透明。
<Window x:Class="WpfApp1.WelcomeWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="Welcome Window" Height="350" Width="525" WindowStartupLocation="CenterScreen"><Window.Resources><Storyboard x:Key="WelcomeAnimationStoryboard"><DoubleAnimationStoryboard.TargetName="AppIcon"Storyboard.TargetProperty="Width"From="50" To="150" Duration="0:0:2"><DoubleAnimation.EasingFunction><BackEase EasingMode="EaseOut"/></DoubleAnimation.EasingFunction></DoubleAnimation><DoubleAnimationStoryboard.TargetName="AppIcon"Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"From="0" To="360" Duration="0:0:2"/><DoubleAnimationStoryboard.TargetName="WelcomeText"Storyboard.TargetProperty="Opacity"From="0" To="1" Duration="0:0:1.5" BeginTime="0:0:0.5"/></Storyboard><RotateTransform x:Key="AppIconRotateTransform" Angle="0"/></Window.Resources><Grid><Ellipse x:Name="AppIcon" Width="50" Height="50" Fill="Blue" HorizontalAlignment="Center" VerticalAlignment="Center"><Ellipse.RenderTransform><RotateTransform x:Name="AppIconRotateTransform" Angle="0"/></Ellipse.RenderTransform><Ellipse.Triggers><EventTrigger RoutedEvent="Ellipse.Loaded"><BeginStoryboard Storyboard="{StaticResource WelcomeAnimationStoryboard}"/></EventTrigger></Ellipse.Triggers></Ellipse><TextBlock x:Name="WelcomeText" Text="欢迎使用本应用" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Center" Opacity="0"/></Grid>
</Window>
在这个欢迎界面中,应用程序图标在 2 秒内逐渐放大,同时旋转 360 度,使用BackEase
缓动函数使放大效果更自然。欢迎文字在 0.5 秒后开始从透明渐变到不透明,持续 1.5 秒,整个动画营造出一个生动的欢迎氛围。
6.2 实现动态菜单交互效果
对于应用程序的菜单,我们可以使用动画来增强其交互性。例如,当鼠标悬停在菜单项上时,菜单项可以向右滑动并改变颜色,给用户提供直观的反馈。
<Window x:Class="WpfApp1.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="Dynamic Menu Example" Height="350" Width="525"><Window.Resources><Storyboard x:Key="MenuItemHoverStoryboard"><DoubleAnimationStoryboard.TargetName="MenuItem"Storyboard.TargetProperty="Margin.Left"From="0" To="10" Duration="0:0:0.2"/><ColorAnimationStoryboard.TargetName="MenuItemText"Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"From="Black" To="Blue" Duration="0:0:0.2"/></Storyboard><Storyboard x:Key="MenuItemLeaveStoryboard"><DoubleAnimationStoryboard.TargetName="MenuItem"Storyboard.TargetProperty="Margin.Left"From="10" To="0" Duration="0:0:0.2"/><ColorAnimationStoryboard.TargetName="MenuItemText"Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"From="Blue" To="Black" Duration="0:0:0.2"/></Storyboard></Window.Resources><Grid><StackPanel Orientation="Vertical"><StackPanel x:Name="MenuItem" Orientation="Horizontal" Margin="5" Background="White"><Rectangle Width="10" Height="10" Fill="Gray"/><TextBlock x:Name="MenuItemText" Text="文件" Margin="5" Foreground="Black"/><StackPanel.Triggers><EventTrigger RoutedEvent="StackPanel.MouseEnter"><BeginStoryboard Storyboard="{StaticResource MenuItemHoverStoryboard}"/></EventTrigger><EventTrigger RoutedEvent="StackPanel.MouseLeave"><BeginStoryboard Storyboard="{StaticResource MenuItemLeaveStoryboard}"/></EventTrigger></StackPanel.Triggers></StackPanel><!-- 其他菜单项 --></StackPanel></Grid>
</Window>
在这个示例中,当鼠标进入菜单项时,触发MenuItemHoverStoryboard
动画,菜单项向左移动 10 个单位,同时文字颜色变为蓝色;当鼠标离开时,触发MenuItemLeaveStoryboard
动画,菜单项和文字颜色恢复原状,通过这种简单的动画效果,提升了菜单的交互体验。
七、性能优化与注意事项
7.1 性能优化
在使用 WPF 动画时,性能优化是一个重要的考虑因素。以下是一些优化建议:
减少不必要的动画:避免在界面上同时运行过多的动画,尤其是复杂的动画,因为这可能会消耗大量的系统资源,导致界面卡顿。只在必要的情况下使用动画,并且确保动画的持续时间和复杂度是合理的。
使用硬件加速:WPF 支持硬件加速,通过合理设置,可以利用显卡的性能来提高动画的流畅度。例如,对于一些涉及大量图形变换的动画,可以将RenderOptions.EdgeMode属性设置为Aliased,启用硬件加速。
优化动画代码:尽量减少动画代码中的计算量,避免在动画过程中进行复杂的逻辑处理。可以将一些预计算的结果缓存起来,减少动画运行时的计算开销。
7.2 注意事项
动画兼容性:在不同的操作系统和硬件环境下,动画的表现可能会有所不同。在开发过程中,需要在多种环境下进行测试,确保动画在各种情况下都能正常运行且表现一致。
依赖属性的选择:在选择要进行动画的依赖属性时,要确保该属性的变化不会对其他功能产生负面影响。例如,某些属性的动画可能会影响控件的布局或事件处理,需要谨慎处理。
动画的可维护性:随着项目的发展,动画代码可能会变得复杂。为了提高代码的可维护性,建议将动画相关的代码进行合理的封装和组织,使用资源字典来管理动画资源,使代码结构更加清晰。
八、总结
WPF 动画特效为开发者提供了强大的工具,能够创建出各种炫酷的界面交互效果,极大地提升用户体验。通过本文对 WPF 动画基础概念、各种动画类型、高级应用技巧以及实际应用案例的深入讲解,相信读者已经对 WPF 动画有了全面的了解。在实际开发中,需要根据具体的需求和场景,灵活运用这些知识,同时注意性能优化和相关注意事项,打造出高效、美观且交互性强的应用程序界面。随着技术的不断发展,WPF 动画也在不断演进,开发者可以持续关注相关技术动态,不断探索和创新,为用户带来更出色的视觉体验。
结束语
展望未来,WPF 布局系统依然有着广阔的发展前景。随着硬件技术的不断革新,如高分辨率屏幕、折叠屏设备的日益普及,WPF 布局系统有望进一步强化其自适应能力,为用户带来更加流畅、一致的体验。在应对高分辨率屏幕时,能够更加智能地缩放和布局元素,确保文字清晰可读、图像不失真;对于折叠屏设备,可动态调整布局结构,充分利用多屏空间,实现无缝切换。
性能优化方面,微软及广大开发者社区将持续努力,进一步降低复杂布局的计算开销,提高布局更新的效率,使得 WPF 应用在处理大规模数据、动态界面时依然能够保持高效响应。通过改进算法、优化内存管理等手段,让 WPF 布局系统在性能上更上一层楼。
亲爱的朋友,无论前路如何漫长与崎岖,都请怀揣梦想的火种,因为在生活的广袤星空中,总有一颗属于你的璀璨星辰在熠熠生辉,静候你抵达。
愿你在这纷繁世间,能时常收获微小而确定的幸福,如春日微风轻拂面庞,所有的疲惫与烦恼都能被温柔以待,内心永远充盈着安宁与慰藉。
至此,文章已至尾声,而您的故事仍在续写,不知您对文中所叙有何独特见解?期待您在心中与我对话,开启思想的新交流。
优质源码分享
-
【百篇源码模板】html5各行各业官网模板源码下载
-
【模板源码】html实现酷炫美观的可视化大屏(十种风格示例,附源码)
-
【VUE系列】VUE3实现个人网站模板源码
-
【HTML源码】HTML5小游戏源码
-
【C#实战案例】C# Winform贪吃蛇小游戏源码
💞 关注博主 带你实现畅游前后端
🏰 大屏可视化 带你体验酷炫大屏
💯 神秘个人简介 带你体验不一样得介绍
🎀 酷炫邀请函 带你体验高大上得邀请
① 🉑提供云服务部署(有自己的阿里云);
② 🉑提供前端、后端、应用程序、H5、小程序、公众号等相关业务;
如🈶合作请联系我,期待您的联系。
注:本文撰写于CSDN平台,作者:xcLeigh(所有权归作者所有) ,https://blog.csdn.net/weixin_43151418,如果相关下载没有跳转,请查看这个地址,相关链接没有跳转,皆是抄袭本文,转载请备注本文原地址。
亲,码字不易,动动小手,欢迎 点赞 ➕ 收藏,如 🈶 问题请留言(评论),博主看见后一定及时给您答复,💌💌💌
原文地址:https://blog.csdn.net/weixin_43151418/article/details/145323044(防止抄袭,原文地址不可删除)
相关文章:
WPF进阶 | WPF 动画特效揭秘:实现炫酷的界面交互效果
WPF进阶 | WPF 动画特效揭秘:实现炫酷的界面交互效果 前言一、WPF 动画基础概念1.1 什么是 WPF 动画1.2 动画的基本类型1.3 动画的核心元素 二、线性动画详解2.1 DoubleAnimation 的使用2.2 ColorAnimation 实现颜色渐变 三、关键帧动画深入3.1 DoubleAnimationUsin…...
基于微信小程序的辅助教学系统的设计与实现
标题:基于微信小程序的辅助教学系统的设计与实现 内容:1.摘要 摘要:随着移动互联网的普及和微信小程序的兴起,基于微信小程序的辅助教学系统成为了教育领域的一个新的研究热点。本文旨在设计和实现一个基于微信小程序的辅助教学系统,以提高教…...
给AI加知识库
1、加载 Document Loader文档加载器 在 langchain_community. document_loaders 里有很多种文档加载器 from langchain_community. document_loaders import *** 1、纯文本加载器:TextLoader,纯文本(不包含任何粗体、下划线、字号格式&am…...
【LeetCode 刷题】回溯算法(5)-棋盘问题
此博客为《代码随想录》二叉树章节的学习笔记,主要内容为回溯算法棋盘问题相关的题目解析。 文章目录 51. N皇后37. 解数独332.重新安排行程 51. N皇后 题目链接 class Solution:def solveNQueens(self, n: int) -> List[List[str]]:board [[. for _ in rang…...
Vue.js组件开发-实现字母向上浮动
使用Vue实现字母向上浮动的效果 实现步骤 创建Vue项目:使用Vue CLI来创建一个新的Vue项目。定义组件结构:在组件的模板中,定义包含字母的元素。添加样式:使用CSS动画来实现字母向上浮动的效果。绑定动画类:在Vue组件…...
2025蓝桥杯JAVA编程题练习Day2
1.大衣构造字符串 问题描述 已知对于一个由小写字母构成的字符串,每次操作可以选择一个索引,将该索引处的字符用三个相同的字符副本替换。 现有一长度为 NN 的字符串 UU,请帮助大衣构造一个最小长度的字符串 SS,使得经过任意次…...
WPF进阶 | WPF 样式与模板:打造个性化用户界面的利器
WPF进阶 | WPF 样式与模板:打造个性化用户界面的利器 一、前言二、WPF 样式基础2.1 什么是样式2.2 样式的定义2.3 样式的应用 三、WPF 模板基础3.1 什么是模板3.2 控件模板3.3 数据模板 四、样式与模板的高级应用4.1 样式继承4.2 模板绑定4.3 资源字典 五、实际应用…...
趣味Python100例初学者练习01
1. 1 抓交通肇事犯 一辆卡车违反交通规则,撞人后逃跑。现场有三人目击该事件,但都没有记住车号,只记下了车号的一些特征。甲说:牌照的前两位数字是相同的;乙说:牌照的后两位数字是相同的,但与前…...
每日一题——有效括号序列
有效括号序列 题目描述数据范围:复杂度要求: 示例题解代码实现代码解析1. 定义栈和栈操作2. 栈的基本操作3. 主函数 isValid4. 返回值 时间和空间复杂度分析 题目描述 给出一个仅包含字符 (, ), {, }, [, ] 的字符串,判断该字符串是否是一个…...
MQTT 术语表
Broker 有时我们也会直接将服务端称为 Broker,这两个术语可以互换使用。 Clean Start 客户端可以在连接时使用这个字段来指示是期望从已存在的会话中恢复通信,还是创建一个全新的会话。仅限 MQTT v5.0。 Client 使用 MQTT 协议连接到服务端的设备或…...
每天学点小知识之设计模式的艺术-策略模式
行为型模式的名称、定义、学习难度和使用频率如下表所示: 1.如何理解模板方法模式 模板方法模式是结构最简单的行为型设计模式,在其结构中只存在父类与子类之间的继承关系。通过使用模板方法模式,可以将一些复杂流程的实现步骤封装在一系列基…...
ubuntuCUDA安装
系列文章目录 移动硬盘制作Ubuntu系统盘 前言 根据前篇“移动硬盘制作Ubuntu系统盘”安装系统后,还不能够使用显卡。 如果需要使用显卡,还需要进行相关驱动的安装(如使用的为Nvidia显卡,就需要安装相关的Nvidia显卡驱动ÿ…...
信息学奥赛一本通 2113:【24CSPJ普及组】小木棍(sticks) | 洛谷 P11229 [CSP-J 2024] 小木棍
【题目链接】 ybt 2113:【24CSPJ普及组】小木棍(sticks) 洛谷 P11229 [CSP-J 2024] 小木棍 【题目考点】 1. 思维题,找规律 【解题思路】 解法1:找规律 该题为:求n根木棍组成的无前导0的所有可能的数…...
【数据结构】(5) ArrayList 顺序表
一、使用 ArrayList ArrayList 就是数组的封装,但是数组只有 [] 操作存取值,和 .length 操作获取数组内存长度;而 ArrayList 有更多的功能: 1、创建对象 2、扩容机制 ArrayList 有自动扩容机制,在插入元素时不用担心数…...
Elasticsearch 指南 [8.17] | Search APIs
Search API 返回与请求中定义的查询匹配的搜索结果。 http GET /my-index-000001/_search Request GET /<target>/_search GET /_search POST /<target>/_search POST /_search Prerequisites 如果启用了 Elasticsearch 安全功能,针对目标数据流…...
【自开发工具介绍】SQLSERVER的ImpDp和ExpDp工具03
SQLSERVER的ImpDp和ExpDp工具 1、全部的表导出(仅表结构导出) 2、导出的表结构,导入到新的数据库 导入前,test3数据没有任何表 导入 导入结果确认:表都被做成,但是没有数据 3、全部的表导出&#x…...
JVM-运行时数据区
JVM的组成 运行时数据区-总览 Java虚拟机在运行Java程序过程中管理的内存区域,称之为运行时数据区。 《Java虚拟机规范》中规定了每一部分的作用 运行时数据区-应用场景 Java的内存分成哪几部分? Java内存中哪些部分会内存溢出? JDK7 和J…...
经典本地影音播放器MPC-BE.
经典本地影音播放器MPC-BE 链接:https://pan.xunlei.com/s/VOIAZbbIuBM1haFdMYCubsU-A1?pwd4iz3# MPC-BE(Media Player Classic Black Edition)是来自 MPC-HC(Media Player Classic Home Cinema)的俄罗斯开发者重新…...
求水仙花数,提取算好,打表法。或者暴力解出来。
暴力解法 #include<bits/stdc.h> using namespace std; int main() {int n,m;cin>>n>>m;if(n<3||n>7||m<0){cout<<"-1";return 0;}int powN[10];//记录0-9的n次方for(int i0;i<10;i){powN[i](int)pow(i,n);}int low(int) pow(1…...
后盾人JS -- 原型
没有原型的对象 也有没有原型的对象 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document<…...
Deepseek-R1 和 OpenAI o1 这样的推理模型普遍存在“思考不足”的问题
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
Nginx 命令行参数
文章来源:命令行参数 -- nginx中文文档|nginx中文教程 nginx 支持以下命令行参数: -?| — 打印帮助 以获取命令行参数。-h-c file— 使用替代项 configuration 而不是 default 文件。file-e file— 使用替代项 error log 来存储日志 而不是默认文件 &…...
YOLOV11-1:YoloV11-安装和CLI方式训练模型
YoloV11-安装和CLI方式训练模型 1.安装和运行1.1安装的基础环境1.2安装yolo相关组件1.3命令行方式使用1.3.1 训练1.3.2 预测 本文介绍yoloV11的安装和命令行接口 1.安装和运行 1.1安装的基础环境 GPU环境,其中CUDA是12.4版本 1.2安装yolo相关组件 # 克隆github…...
Docker Hub 镜像 Pull 失败的解决方案
目录 引言一、问题二、原因三、解决方法四、参考文献 引言 在云原生技术火热的当下,Docker可谓是其基础,由于其简单以及方便性,让开发人员不必再为环境配置问题而伤脑筋,因为可将其看作一个虚拟机程序去理解。所以掌握好它可谓是…...
重新思考绩效管理变革
Peter Cappelli 和 Anna Tavis 在绩效管理变革一文中,为我们带来了很多关于绩效管理变革的思考。企业为什么做绩效管理变革,为什么现在需要?让我们看看这些学者是如何思考的。 摘要 受到老板和下属的痛恨,传统的绩效考核已经被超…...
内核定时器2-高分辨率定时器
高分辨率定时器与低分辨率定时器 高分辨率定时器与低分辨率定时器相比,有如下两个根本性的不同。 (1) 高分辨率定时器使用红黑树对定时器进行管理。 (2) 定时器独立于周期时钟。即不基于jiffies,精度可以达到纳秒级别。 内核2.6.16版本开始ÿ…...
【自开发工具介绍】SQLSERVER的ImpDp和ExpDp工具02
工具运行前的环境准备 1、登录用户管理员权限确认 工具使用的登录用户(-u后面的用户),必须具有管理员的权限,因为需要读取系统表 例:Export.bat -s 10.48.111.12 -d db1 -u test -p test -schema dbo 2、Powershell的安全策略确认…...
数据结构【单链表操作大全详解】【c语言版】(只有输入输出为了方便用的c++)
单链表操作的C/C实现详解 在数据结构中,单链表是一种非常基础且重要的数据结构。它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。今天我们就来深入探讨用C/C实现的单链表及其各种操作。 一、单链表的定义 const int N 1e5; //单链表 t…...
【R语言】环境空间
一、环境空间种类 R语言中有5种环境: 全局环境:也叫用户环境,指在当前用户下R程序运行的环境空间。 内部环境:通过“new.env()”命令创建的环境空间,也可以是匿名的环境空间。 父环境:当前环境空间所处…...
Python处理数据库:MySQL与SQLite详解
Python处理数据库:MySQL与SQLite详解 在数据处理和存储方面,数据库扮演着至关重要的角色。Python提供了多种与数据库交互的方式,其中pymysql库用于连接和操作MySQL数据库,而SQLite则是一种轻量级的嵌入式数据库,Pytho…...
软考高项笔记 信息技术及其发展
信息技术及其发展 ❝ 信息系统项目管理师第二章第一节 1. 网络标准协议的定义 网络协议是为计算机网络中进行数据交换而建立的规则、标准或约定的集合。网络协议由三个要素组成,分别是语义、语法和时序。 语义:解释控制信息每个部分的含义,它…...
HAO的Graham学习笔记
前置知识:凸包 摘录oiwiki 在平面上能包含所有给定点的最小凸多边形叫做凸包。 其定义为:对于给定集合 X,所有包含 X 的凸集的交集 S 被称为 X 的 凸包。 说人话就是用一个橡皮筋包含住所有给定点的形态 如图: 正题:…...
C#基础知识
0 C#介绍 定义与背景 C#(发音为C - sharp)是微软公司开发的一种高级编程语言。它是专门为构建在微软的.NET平台上运行的各种应用程序而设计的。在2000年左右推出,目的是结合当时编程语言的优点,如C的强大功能和Java的简单性与安全…...
Kafka中文文档
文章来源:https://kafka.cadn.net.cn 什么是事件流式处理? 事件流是人体中枢神经系统的数字等价物。它是 为“永远在线”的世界奠定技术基础,在这个世界里,企业越来越多地使用软件定义 和 automated,而软件的用户更…...
Tyrant(暴君):反向Shell-后门注入与持久化控制的渗透测试工具
Tyrant Tyrant 是一款用于渗透测试和远程控制持久化的恶意工具,具备以下功能: 反向Shell:允许攻击者通过指定用户UID进行反弹对应权限的Shell会话。后门注入与持久化:在目标系统中注入后门并确保即使重启后依然能恢复控制。Tyran…...
leetcode刷题-贪心04
代码随想录贪心算法part04|452. 用最少数量的箭引爆气球、435. 无重叠区间、763.划分字母区间 452. 用最少数量的箭引爆气球435. 无重叠区间763.划分字母区间 今天的三道题目,都算是 重叠区间 问题,大家可以好好感受一下。 都属于那种看起来好复杂&#…...
系统学习算法: 专题八 二叉树中的深搜
深搜其实就是深度优先遍历(dfs),与此相对的还有宽度优先遍历(bfs) 如果学完数据结构有点忘记,如下图,左边是dfs,右边是bfs 而二叉树的前序,中序,后序遍历都可…...
2022年全国职业院校技能大赛网络系统管理赛项模块A:网络构建(样题2)-网络部分解析-附详细代码
目录 附录1:拓扑图编辑 附录2:地址规划表 1.SW1 2.SW2 3.SW3 4.SW4 5.SW5 6.SW6 7.SW7 8.R1 9.R2 10.R3 11.AC1 12.AC2 13.EG1 14.EG2 15.AP2 16.AP3 附录1:拓扑图 附录2:地址规划表...
笔试-业务逻辑4
应用 小明在玩一个数字加减游戏,输入4个正整数:s、t、a、b,其中s>1,b<105,a!b。只使用加法或者减法,使得st。 每回合,小明用当前的数字,加上或减去一个数字;目前有…...
冷启动+强化学习:DeepSeek-R1 的原理详解——无需监督数据的推理能力进化之路
本文基于 DeepSeek 官方论文进行分析,论文地址为:https://github.com/deepseek-ai/DeepSeek-R1/blob/main/DeepSeek_R1.pdf 有不足之处欢迎评论区交流 原文翻译 在阅读和理解一篇复杂的技术论文时,逐字翻译是一个重要的步骤。它不仅能帮助我们准确把握作者的原意,还能为后续…...
ubuntu22安装issac gym记录
整体参考:https://blog.csdn.net/Yakusha/article/details/144306858 安装完成后的整体版本信息 ubuntu:22.04内核:6.8.0-51-generic显卡:NVIDIA GeForce RTX 3050 OEM显卡驱动:535.216.03cuda:12.2cudnn&…...
Docker小游戏 | 使用Docker部署2048网页小游戏
Docker小游戏 | 使用Docker部署2048网页小游戏 前言项目介绍项目简介项目预览二、系统要求环境要求环境检查Docker版本检查检查操作系统版本三、部署2048网页小游戏下载镜像创建容器检查容器状态检查服务端口安全设置四、访问2048网页小游戏五、总结前言 在当今快速发展的技术世…...
C基础寒假练习(2)
一、输出3-100以内的完美数,(完美数:因子和(因子不包含自身)数本身 #include <stdio.h>// 函数声明 int isPerfectNumber(int num);int main() {printf("3-100以内的完美数有:\n");for (int i 3; i < 100; i){if (isPerfectNumber…...
传输层协议 UDP 与 TCP
🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 目录 一:🔥 前置复盘🦋 传输层🦋 再谈端口号🦋 端口号范围划分🦋 认识知名端口号 (Well-Know Port Number) 二…...
Vue06
目录 一、声明式导航-导航链接 1.需求 2.解决方案 3.通过router-link自带的两个样式进行高亮 二、声明式导航的两个类名 1.router-link-active 2.router-link-exact-active 三、声明式导航-自定义类名(了解) 1.问题 2.解决方案 3.代码演示 四…...
AJAX笔记进阶篇
黑马程序员视频地址: AJAX-Day04-01.同步代码和异步代码https://www.bilibili.com/video/BV1MN411y7pw?vd_source0a2d366696f87e241adc64419bf12cab&spm_id_from333.788.videopod.episodes&p47 同步代码和异步代码 回调函数地狱与解决方法 回调函数地狱…...
Linux+Docer 容器化部署之 Shell 语法入门篇 【Shell 循环类型】
文章目录 一、Shell 循环类型二、Shell while 循环三、Shell for 循环四、Shell until 循环五、Shell select 循环六、总结 一、Shell 循环类型 循环是一个强大的编程工具,使您能够重复执行一组命令。在本教程中,您将学习以下类型的循环 Shell 程序&…...
【Redis】安装配置Redis超详细教程 / Linux版
Linux安装配置Redis超详细教程 安装redis依赖安装redis启动redis停止redisredis.conf常见配置设置redis为后台启动修改redis监听地址设置工作目录修改密码监听的端口号数据库数量设置redis最大内存设置日志文件设置redis开机自动启动 学习视频:黑马程序员Redis入门到…...
S4 HANA明确税金汇差科目(OBYY)
本文主要介绍在S4 HANA OP中明确税金汇差科目(OBYY)相关设置。具体请参照如下内容: 1. 明确税金汇差科目(OBYY) 以上配置点定义了在外币挂账时,当凭证抬头汇率和税金行项目汇率不一致时,造成的差异金额进入哪个科目。此类情况只发生在FB60/F…...
Nginx反向代理 笔记250203
Nginx反向代理 Nginx 是一个高性能的 HTTP 服务器和反向代理服务器。反向代理是指客户端请求资源时,Nginx 作为中间层,将请求转发到后端服务器,并将后端服务器的响应返回给客户端。通过反向代理,可以实现负载均衡、缓存、SSL 终端…...