WPF 动画类型回顾

WPF-关于动画Animation(及其常见问题) StrokeDashOffset:分段偏移值(改变该值实现流动效果)="0.5,0.5",切换位置转换的中心点;StrokeDashArray :分段长度。得自己规划逻辑(触发器、事件都可) 阅读详情

创建动画面临的第一个挑战是为动画选择正确的属性。期望的结果(例如,在窗口中移动元素)与需要使用的属性(在这种情况下是Canvas.Left和Canvas.Top属性)之间的关系并不总是很直观。下面是一些指导原则:

  •   如果希望使用动画来使元素显示和消失,不要使用Visibility属性(该属性只能在完全可见和完全不可见之间进行切换)。应改用Opacity属性淡入或淡出元素。
  •   如果希望动态改变元素的位置,可考虑使用Canvas面板。它提供了最直接的属性(Canvas.Left及Canvas.Top),而且开销最小。此外,也可使用动画属性在其他布局容器中获得类似效果。例如,可通过使用ThicknessAnimation类动态改变Margin和Padding等属性,还可动态改变Grid控件中的MinWidth或MinHeight属性、一列或一行。
  •   动画最常用的属性是渲染变换。可使用变换移动或翻转元素(TranslateTransform)、旋转元素(RotateTransform)、缩放或扭曲元素(ScaleTransform)等。通过仔细地使用变换,有时可避免在动画中硬编码尺寸和位置。它们也绕过了WPF布局系统,比直接作用于元素大小或位置的其他方法速度更快。
  •   动态改变元素表面的较好方法是修改画刷属性。可使用ColorAnimation改变颜色或其他动画对象来变换更复杂画刷的属性,如渐变中的偏移。

  接下来的示例演示了如何动态改变变换和画刷,以及如何使用更多的一些动画类型。还将讨论如何使用关键帧创建多段动画、如何创建基于路径的动画和基于帧的动画。

一、动态变换

  变换提供了自定义元素的最强大方式之一。当使用变换时,不只是改变元素的边界,而且会移动、翻转、扭曲、拉伸、放大、缩小或旋转元素的整个可视化外观。例如,可通过ScaleTransform动态改变按钮的尺寸,这会改变整个按钮的尺寸,包括按钮的边框及其内部的内容。这种效果比动态改变Width和Height属性或改变文本的Fontsize属性给人的印象更深刻。

  前面章节了解到,每个元素都能以两种不同的方式使用变换:RenderTransform属性和LayoutTransform属性。RenderTransform效率更高,因为是在布局之后应用变换并且勇于变换最终的渲染输出。LayoutTransform在布局前应用,从而其他控件需要重新排列以适应变换。改变LayoutTransform属性会引发新的布局操作(除非在Canvas面板上使用元素,在这种情况下,RenderTransform和LayoutTransform的效果相同)。

  为在动画中使用变换,第一步是定义变换(动画可改变已经存在的变换,但不能创建新的变换)。例如,假设希望使按钮旋转,此时需要使用RotateTransform对象:

<Button Content="A Button">
    <RenderTransform>
        <RotateTransform></RotateTransform>
    </RenderTransform>
</Button>

现在当将鼠标移动到按钮上时,下面的事件触发器就会旋转按钮。使用的目标属性是RenderTransform.Angle——换句话说,读取按钮的RenderTransform属性并修改其中定义的RotateTransform对象的Angle属性。事实上,RenderTransform属性可包含各种不同的变换对象,每种变换对象的属性各不相同,这不会引起问题。只要使用的变换具有Angle属性,这个触发器就能工作:

<EventTrigger RoutedEvent="Button.MouseEnter">
    <EventTrigger.Actions>
          <BeginStoryboard Name="rotateStoryboardBegin">
               <Storyboard>
                     <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle"
                 To="360" Duration="0:0:0.8" RepeatBehavior="Forever"></DoubleAnimation>
                </Storyboard>
           </BeginStoryboard>
     </EventTrigger.Actions>
</EventTrigger>

按钮在0.8秒得时间内旋转一周并且持续旋转。当按钮旋转时仍完全可用——例如,可单击按钮并处理Click事件。

  为保证按钮绕其中心旋转(而不是绕左上角旋转),需要按如下方式设置RenderTransformOrigin属性:

<Button RenderTransformOrigin="0.5,0.5"/>

请记住,RenderTransformOrigin属性使用0~1的相对单位,所以0.5表示中点。

  为停止旋转,可使用第二个触发器响应MouseLeave事件。这是,可删除执行旋转的故事板,但这会导致按钮一步调回到它原来的位置。更好的方法是开始第二个动画,用它替代第一个动画。这个动画忽略To和From属性,这意味着它无缝地再0.2秒得时间内将按钮旋转回原始方向:

<EventTrigger RoutedEvent="Button.MouseLeave">
    <EventTrigger.Actions>
         <BeginStoryboard>
              <Storyboard>
                  <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle"
                   Duration="0:0:0.2"></DoubleAnimation>
               </Storyboard>
          </BeginStoryboard>
    </EventTrigger.Actions>
</EventTrigger>

为创建旋转的按钮,需要为Button.Triggers集合添加这两个触发器。或将它们(以及变换)放到一个样式中,并根据需要为多个按钮应用这个样式。例如,下面的窗口标记充满了下图中显示的“能旋转的”按钮:

<Window x:Class="Animation.RotateButton"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="RotateButton" Height="300" Width="300">
    <Window.Resources>

        <Style TargetType="{x:Type Button}">
            <Setter Property="HorizontalAlignment" Value="Center"></Setter>
            <Setter Property="RenderTransformOrigin" Value="0.5,0.5"></Setter>
            <Setter Property="Padding" Value="20,15"></Setter>
            <Setter Property="Margin" Value="2"></Setter>
            <Setter Property="RenderTransform">
                <Setter.Value>
                    <RotateTransform></RotateTransform>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <EventTrigger RoutedEvent="Button.MouseEnter">
                    <EventTrigger.Actions>
                        <BeginStoryboard Name="rotateStoryboardBegin">
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle"
                 To="360" Duration="0:0:0.8" RepeatBehavior="Forever"></DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
                <EventTrigger RoutedEvent="Button.MouseLeave">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle"
                   Duration="0:0:0.2"></DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
            </Style.Triggers>
        </Style>

    </Window.Resources>
    <StackPanel Margin="5" Button.Click="cmd_Clicked">
        <Button>One</Button>
        <Button>Two</Button>
        <Button>Three</Button>
        <Button>Four</Button>
        <TextBlock Name="lbl" Margin="5"></TextBlock>
    </StackPanel>
</Window>

在单击任何按钮时,都会在TextBlock元素中显示一条信息。

这个示例还未分析渲染变换和布局变换之间的区别提供了绝佳的机会。如果修改代码可使用LayoutTransform属性,那么会发现当旋转其中一个按钮时,其他按钮会被推离原来的位置。例如,如果旋转最上面的按钮,下面的按钮会上下跳动以避开顶部的按钮。

<Window x:Class="Animation.RotateButtonWithLayout"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="RotateButtonWithLayout" Height="300" Width="300">
    <Window.Resources>

        <Style TargetType="{x:Type Button}">
            <Setter Property="HorizontalAlignment" Value="Center"></Setter>
            <Setter Property="RenderTransformOrigin" Value="0.5,0.5"></Setter>
            <Setter Property="Padding" Value="20,15"></Setter>
            <Setter Property="Margin" Value="2"></Setter>
            <Setter Property="LayoutTransform">
                <Setter.Value>
                    <RotateTransform></RotateTransform>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <EventTrigger RoutedEvent="Button.MouseEnter">
                    <EventTrigger.Actions>
                        <BeginStoryboard Name="rotateStoryboardBegin">
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="LayoutTransform.Angle"
                 To="360" Duration="0:0:0.8" RepeatBehavior="Forever"></DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
                <EventTrigger RoutedEvent="Button.MouseLeave">
                    <EventTrigger.Actions>
                        <!-- <RemoveStoryboard BeginStoryboardName="rotateStoryboardBegin"></RemoveStoryboard> -->
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="LayoutTransform.Angle"
                   Duration="0:0:0.2"></DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
            </Style.Triggers>
        </Style>

    </Window.Resources>
    <StackPanel Margin="5" Button.Click="cmd_Clicked">
        <Button>One</Button>
        <Button>Two</Button>
        <Button>Three</Button>
        <Button>Four</Button>
        <TextBlock Name="lbl" Margin="5"></TextBlock>
    </StackPanel>
</Window>

 

 

动态改变多个变换

  可很容易地组合使用变换。实际上这是很容易——只需要使用TransformGroup对象设置LayoutTransform或RenderTransform属性即可。可根据需要在TransformGroup对象中嵌套任意多个变换。

  下图显示了一个使用两个变换创建的有趣效果。文档窗口刚开始作为主窗口左上角的小缩略图。当文档窗口显示时,内容旋转、扩展并快速淡入到试图中,从概念上讲,这与最大化窗口时Windows使用的效果类似。在WPF中,可通过变换为所有的元素应用这种技巧。

 为创建这种效果,在如下TransformGroup对象中定义了两个变换,并使用TransformGroup对象设置包含所有内容的Board对象的RenderTransform属性:

<Border.RenderTransform>
     <TransformGroup>
           <ScaleTransform></ScaleTransform>
            <RotateTransform></RotateTransform>
      </TransformGroup>
</Border.RenderTransform>

 通过指定数字偏移值(0用于首先显示的ScaleTransform对象,1用于接下来显示的RotateTransform对象),动画可与这两个变换对象进行交互。例如,下面的动画放大内容:

<DoubleAnimation Storyboard.TargetName="element"
                                Storyboard.TargetProperty="RenderTransform.Children[0].ScaleX"
                                From="0" To="1" Duration="0:0:2" AccelerationRatio="1"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="element"
                                Storyboard.TargetProperty="RenderTransform.Children[0].ScaleY"
                                From="0" To="1" Duration="0:0:2" AccelerationRatio="1"></DoubleAnimation>

下面的动画位于相同的故事板中,用于旋转内容:

<DoubleAnimation Storyboard.TargetName="element"
                                Storyboard.TargetProperty="RenderTransform.Children[1].Angle"
                                From="70" To="0" Duration="0:0:2" ></DoubleAnimation>

 这个动画中的内容比此处显示的内容还多。例如,还有一个同时增加Opacity属性的动画,并且当Borad元素达到最大尺寸时,它短暂地向后"反弹"一下,创建一种更趋自然的效果。为这个动画创建时间线并修改各个动画对象属性需要耗费时间——理想情况下,可使用诸如Expression Blend的设计工具执行这些任务,而不是通过手动编写代码来完成这些任务。甚至更好的情况下,只要有第三方开发者将这一逻辑分组到自定义动画中,就可以重用并根据需要将其应用到对象上(根据目前的情况,可通过将Storyboard对象存储为应用程序级的资源,重用这个动画)。

  下面是完整的XAML标记:

<Window x:Class="Animation.ExpandElement"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpandElement" Height="423.2" Width="488.8" WindowStartupLocation="CenterScreen">
    <Window.Triggers>
        <EventTrigger RoutedEvent="Window.Loaded">
            <EventTrigger.Actions>
                <BeginStoryboard>
                    <Storyboard SpeedRatio="1.5">
                        <DoubleAnimation Storyboard.TargetName="element"
                                Storyboard.TargetProperty="Opacity"
                                From="0.2" To="1" Duration="0:0:2.5"></DoubleAnimation>
                        <DoubleAnimation Storyboard.TargetName="element"
                                Storyboard.TargetProperty="RenderTransform.Children[1].Angle"
                                From="70" To="0" Duration="0:0:2" ></DoubleAnimation>

                        <DoubleAnimation Storyboard.TargetName="element"
                                Storyboard.TargetProperty="RenderTransform.Children[0].ScaleX"
                                From="0" To="1" Duration="0:0:2" AccelerationRatio="1"></DoubleAnimation>
                        <DoubleAnimation Storyboard.TargetName="element"
                                Storyboard.TargetProperty="RenderTransform.Children[0].ScaleY"
                                From="0" To="1" Duration="0:0:2" AccelerationRatio="1"></DoubleAnimation>

                        <DoubleAnimation Storyboard.TargetName="element"
                                            Storyboard.TargetProperty="RenderTransform.Children[0].ScaleX"
                                            To="0.98" BeginTime="0:0:2" Duration="0:0:0.05"  DecelerationRatio="1"></DoubleAnimation>
                        <DoubleAnimation Storyboard.TargetName="element"
                                Storyboard.TargetProperty="RenderTransform.Children[0].ScaleY"
                                To="0.98" BeginTime="0:0:2" Duration="0:0:0.05" DecelerationRatio="1"></DoubleAnimation>
                        <DoubleAnimation Storyboard.TargetName="element"
                                            Storyboard.TargetProperty="RenderTransform.Children[0].ScaleX"
                                            To="1" BeginTime="0:0:2.05" Duration="0:0:0.2"  AccelerationRatio="1"></DoubleAnimation>
                        <DoubleAnimation Storyboard.TargetName="element"
                                Storyboard.TargetProperty="RenderTransform.Children[0].ScaleY"
                                To="1" BeginTime="0:0:2.05" Duration="0:0:0.2" AccelerationRatio="1"></DoubleAnimation>

                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger.Actions>
        </EventTrigger>
    </Window.Triggers>

    <Grid>
        <!--<Button Name="element">
        <Button.Content>Text</Button.Content>
        <Button.RenderTransform>
          <TransformGroup>
            <ScaleTransform ScaleX="0" ScaleY="0"></ScaleTransform>
            <TranslateTransform></TranslateTransform>
            <RotateTransform Angle="90"></RotateTransform>
          </TransformGroup>
        </Button.RenderTransform>
      </Button>-->
        <Border  Name="element" Margin="3" Background="LightGoldenrodYellow"
               BorderBrush="DarkBlue" BorderThickness="2" CornerRadius="5" >
            <Border.RenderTransform>
                <TransformGroup>
                    <ScaleTransform></ScaleTransform>
                    <RotateTransform></RotateTransform>
                </TransformGroup>
            </Border.RenderTransform>
            <FlowDocumentScrollViewer IsToolBarVisible="True">
                <FlowDocument>

                    <Paragraph xml:space="preserve">The <Italic>foof</Italic> feature is indispensable. You can configure the foof feature using the Foof Options dialog box.</Paragraph>
                    <BlockUIContainer>
                        <Button HorizontalAlignment="Left" Padding="5">Open Foof Options</Button>
                    </BlockUIContainer>


                    <Paragraph FontSize="20pt">Largest Cities in the Year 100</Paragraph>
                    <Table>
                        <Table.Columns>
                            <TableColumn Width="*"></TableColumn>
                            <TableColumn Width="3*"></TableColumn>
                            <TableColumn Width="*"></TableColumn>
                        </Table.Columns>

                        <TableRowGroup  >
                            <TableRow FontWeight="Bold" >
                                <TableCell >
                                    <Paragraph>Rank</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>Name</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>Population</Paragraph>
                                </TableCell>
                            </TableRow>
                            <TableRow>
                                <TableCell>
                                    <Paragraph>1</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>Rome</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>450,000</Paragraph>
                                </TableCell>
                            </TableRow>
                            <TableRow>
                                <TableCell>
                                    <Paragraph>2</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>Luoyang (Honan), China</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>420,000</Paragraph>
                                </TableCell>
                            </TableRow>
                            <TableRow>
                                <TableCell>
                                    <Paragraph>3</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>Seleucia (on the Tigris), Iraq</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>250,000</Paragraph>
                                </TableCell>
                            </TableRow>
                            <TableRow>
                                <TableCell>
                                    <Paragraph>4</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>Alexandria, Egypt</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>250,000</Paragraph>
                                </TableCell>
                            </TableRow>
                            <TableRow>
                                <TableCell>
                                    <Paragraph>5</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>Antioch, Turkey</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>150,000</Paragraph>
                                </TableCell>
                            </TableRow>
                            <TableRow>
                                <TableCell>
                                    <Paragraph>6</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>Anuradhapura, Sri Lanka</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>130,000</Paragraph>
                                </TableCell>
                            </TableRow>
                            <TableRow>
                                <TableCell>
                                    <Paragraph>7</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>Peshawar, Pakistan</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>120,000</Paragraph>
                                </TableCell>
                            </TableRow>
                            <TableRow>
                                <TableCell>
                                    <Paragraph>8</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>Carthage, Tunisia</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>100,000</Paragraph>
                                </TableCell>
                            </TableRow>
                            <TableRow>
                                <TableCell>
                                    <Paragraph>9</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>Suzhou, China</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>n/a</Paragraph>
                                </TableCell>
                            </TableRow>
                            <TableRow>
                                <TableCell>
                                    <Paragraph>10</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>Smyrna, Turkey</Paragraph>
                                </TableCell>
                                <TableCell>
                                    <Paragraph>90,000</Paragraph>
                                </TableCell>
                            </TableRow>
                        </TableRowGroup>
                    </Table>
                </FlowDocument>
            </FlowDocumentScrollViewer>
        </Border>

    </Grid>

</Window>

这种效果非常有用。例如,可使用该效果将注意力吸引到新的内容——例如用户刚刚打开的文件。这种效果可能的变化是无穷无尽的。例如,创建产品目录时,当用户将鼠标悬停在相应的产品名称上时,滑入包含产品细节的面板或将产品图像滚入试图。

二、动态改变画刷

  动态改变画刷是WPF动画中的另一种常用技术,和动态变换同样容易。同样,这种技术使用恰当的动画类型,深入到希望改变的特定子属性。

  下图显示了一个修改RadialGradientBrush画刷的示例。当动画运行时,径向渐变的中心点沿椭圆漂移,从而实现了一种三维效果。同时,外侧的渐变颜色从蓝色变成黑色。

为实现这个效果,需要使用两种尚未分析过的动画类型。ColorAnimation动画在两个颜色之间逐渐混合,创建一种微妙的颜色转移效果。PointAnimation动画可将点从一个位置移到另一个位置(本质上与使用独立DoubleAnimation,通过线性插值同时修改X坐标和Y坐标是相同的)。可使用PointAnimation动画改变使用点构造的图形,或者就像这个示例中那样,改变径向渐变中心点的位置。

  下面是标记定义了椭圆及其画刷:

<Ellipse Name="ellipse" Margin="5" Grid.Row="1" Stretch="Uniform">
   <Ellipse.Fill>
         <RadialGradientBrush
             RadiusX="1" RadiusY="1" GradientOrigin="0.7,0.3">
                    <GradientStop Color="White" Offset="0" ></GradientStop>
                    <GradientStop Color="Blue" Offset="1" ></GradientStop>
          </RadialGradientBrush>

   </Ellipse.Fill>
</Ellipse>

 下面是移动中心点以及改变第二种颜色的两个动画:

<PointAnimationUsingKeyFrames Storyboard.TargetName="ellipse" Storyboard.TargetProperty="Fill.GradientOrigin"
                                           RepeatBehavior="Forever">
                        <LinearPointKeyFrame Value="0.7,0.3" KeyTime="0:0:0"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.3,0.7" KeyTime="0:0:5"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.5,0.9" KeyTime="0:0:8"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.9,0.6" KeyTime="0:0:10"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.8,0.2" KeyTime="0:0:12"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.7,0.3" KeyTime="0:0:14"></LinearPointKeyFrame>

                        <DiscretePointKeyFrame Value="0.7,0.3" KeyTime="0:0:20"></DiscretePointKeyFrame>
                        <DiscretePointKeyFrame Value="0.3,0.7" KeyTime="0:0:25"></DiscretePointKeyFrame>
                        <DiscretePointKeyFrame Value="0.5,0.9" KeyTime="0:0:28"></DiscretePointKeyFrame>
                        <DiscretePointKeyFrame Value="0.9,0.6" KeyTime="0:0:20"></DiscretePointKeyFrame>
                        <DiscretePointKeyFrame Value="0.8,0.2" KeyTime="0:0:22"></DiscretePointKeyFrame>
                        <DiscretePointKeyFrame Value="0.7,0.3" KeyTime="0:0:24"></DiscretePointKeyFrame>
                    </PointAnimationUsingKeyFrames>


                    <ColorAnimation Storyboard.TargetName="ellipse" Storyboard.TargetProperty="Fill.GradientStops[1].Color"
              To="Black"  Duration="0:0:10"
              AutoReverse="True" RepeatBehavior="Forever"></ColorAnimation>

本例网站XAML标记:

<Window x:Class="Animation.AnimateRadialGradient"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="AnimateRadialGradient" Height="300" Width="300" WindowStartupLocation="CenterScreen">
    <Window.Triggers>
        <EventTrigger RoutedEvent="Window.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <PointAnimationUsingKeyFrames Storyboard.TargetName="ellipse" Storyboard.TargetProperty="Fill.GradientOrigin"
                                           RepeatBehavior="Forever">
                        <LinearPointKeyFrame Value="0.7,0.3" KeyTime="0:0:0"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.3,0.7" KeyTime="0:0:5"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.5,0.9" KeyTime="0:0:8"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.9,0.6" KeyTime="0:0:10"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.8,0.2" KeyTime="0:0:12"></LinearPointKeyFrame>
                        <LinearPointKeyFrame Value="0.7,0.3" KeyTime="0:0:14"></LinearPointKeyFrame>

                        <DiscretePointKeyFrame Value="0.7,0.3" KeyTime="0:0:20"></DiscretePointKeyFrame>
                        <DiscretePointKeyFrame Value="0.3,0.7" KeyTime="0:0:25"></DiscretePointKeyFrame>
                        <DiscretePointKeyFrame Value="0.5,0.9" KeyTime="0:0:28"></DiscretePointKeyFrame>
                        <DiscretePointKeyFrame Value="0.9,0.6" KeyTime="0:0:20"></DiscretePointKeyFrame>
                        <DiscretePointKeyFrame Value="0.8,0.2" KeyTime="0:0:22"></DiscretePointKeyFrame>
                        <DiscretePointKeyFrame Value="0.7,0.3" KeyTime="0:0:24"></DiscretePointKeyFrame>
                    </PointAnimationUsingKeyFrames>


                    <ColorAnimation Storyboard.TargetName="ellipse" Storyboard.TargetProperty="Fill.GradientStops[1].Color"
              To="Black"  Duration="0:0:10"
              AutoReverse="True" RepeatBehavior="Forever"></ColorAnimation>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Window.Triggers>
    <Grid>
        <Ellipse Name="ellipse" Margin="5" Grid.Row="1" Stretch="Uniform">
            <Ellipse.Fill>
                <RadialGradientBrush
             RadiusX="1" RadiusY="1" GradientOrigin="0.7,0.3">
                    <GradientStop Color="White" Offset="0" ></GradientStop>
                    <GradientStop Color="Blue" Offset="1" ></GradientStop>
                </RadialGradientBrush>

            </Ellipse.Fill>
        </Ellipse>
    </Grid>
</Window>

通过修改LinearGradientBrush和RadialGradientBrush画刷的颜色和偏移值可创建许多精彩效果。如果还不够,渐变画刷还有自己的RelativeTransform属性,可使用该属性旋转、缩放、拉伸以及扭曲画刷。WPF团队有一个有趣的称为Gradient Obsession的工具,该工具用于构建基于渐变的动画。

VisualBrush画刷

  VisualBrush画刷可获取任意元素的外观,使用该外观可填充另一个表面。其他表面可以是任何内容,从普遍的矩形到文本框中的字母。

  下图显示了一个基本示例。顶部是一个真实的活动按钮。下面通过VisualBrush画刷使用按钮图片填充一个矩形,并通过各种变换效果拉伸并旋转按钮图片。

VisualBrush画刷还为实现一些有趣的动画效果的动画效果提供了可能。例如,不仅可动态显示活动的真实元素,还可动态显示具有相同填充内容的简单矩形。

  为理解这种方法的工作原理,分析这个示例,该例将一个元素放入试图中。当这个动画运行时,处理具有动画的元素的方法和处理其他任意WPF元素的方式相同,这意味着可单击它内部的按钮,或使用键盘滚动内容(如果用户的操作足够迅速的话)。在一些情况下,这可能会令用户感到困惑。在由写情况下,这可能导致性能下降,因为需要额外的开销来变换输入(如鼠标单击),并且和原始元素一起传递输入。

  使用VisualBrush画刷可轻易地代替这种效果。首先,需要创建另一个元素,使用VisualBrush画刷填充该元素。VisualBrush画刷必须根据希望包含动画的元素(在这个示例中,是名为visual的边框)绘制可视化内容。

<Rectangle Grid.Row="1" Name="rectangle" Width="100" Stretch="Uniform" ClipToBounds="False" RenderTransformOrigin="0.5,0.5">
            <Rectangle.Fill>
                <VisualBrush Visual="{Binding ElementName=visual}">

                </VisualBrush>
            </Rectangle.Fill>
            <Rectangle.RenderTransform>

                <TransformGroup>
                    <SkewTransform CenterX="0.5"></SkewTransform>
                    <RotateTransform CenterX="0.5" CenterY="0.5"></RotateTransform>
                </TransformGroup>

            </Rectangle.RenderTransform>
        </Rectangle>

示例完整XAML标记:

<Window x:Class="Animation.AnimateVisual"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="AnimateVisual" Height="300" Width="300" Background="LightGoldenrodYellow" WindowStartupLocation="CenterScreen">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Button Name="visual" HorizontalAlignment="Center" VerticalAlignment="Center">
            <Button.Content>Test</Button.Content>
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <BeginStoryboard>
                        <Storyboard  RepeatBehavior="Forever">
                            <DoubleAnimation Storyboard.TargetName="rectangle"
                                 Storyboard.TargetProperty="RenderTransform.Children[0].AngleY"
                                 To="180" Duration="0:0:15" AutoReverse="True"></DoubleAnimation>
                            <DoubleAnimation Storyboard.TargetName="rectangle"
                                 Storyboard.TargetProperty="RenderTransform.Children[1].Angle"
                                 To="180" Duration="0:0:20" AutoReverse="True"></DoubleAnimation>
                            <DoubleAnimation Storyboard.TargetName="rectangle"
                                 Storyboard.TargetProperty="Opacity"
                                 To="0.1" Duration="0:0:4" AutoReverse="True"></DoubleAnimation>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Button.Triggers>
        </Button>

        <Rectangle Grid.Row="1" Name="rectangle" Width="100" Stretch="Uniform" ClipToBounds="False" RenderTransformOrigin="0.5,0.5">
            <Rectangle.Fill>
                <VisualBrush Visual="{Binding ElementName=visual}">

                </VisualBrush>
            </Rectangle.Fill>
            <Rectangle.RenderTransform>

                <TransformGroup>
                    <SkewTransform CenterX="0.5"></SkewTransform>
                    <RotateTransform CenterX="0.5" CenterY="0.5"></RotateTransform>
                </TransformGroup>

            </Rectangle.RenderTransform>
        </Rectangle>
    </Grid>
</Window>

为将矩形放到与原始元素相同的位置,可将它们同时放到Grid面板的同一个单元格中。改变单元格的尺寸,使其适合原始元素(边框),并拉伸矩形使其相匹配。另一个选择是在真实实用程序上覆盖Canvas面板(然后可将动画属性绑定到下面真实元素的ActualWidth和ActualHeight属性,从而确保对齐)。

  添加矩形后,只需要调整动画来执行动态变化。最后,当动画完成时隐藏矩形

private void storyboardCompleted(object sender,EventArgs e)
{
    rectangle.Visibility=Visibility.Collapsed;
}

三、动态改变像素着色器

  通过“【WPF学习】第四十六章 效果 ”的学习,了解了像素着色器(可为任意元素应用位图风格效果的低级例程,如模糊、辉光以及弯曲效果)的相关内容。就自身而言,像素着色器是一些有趣并且偶尔有用的工具。但通过结合使用动画,他们可变的更通用。可使用它们设计吸引眼球的过渡效果(例如,通过模糊控件使其淡出、隐藏,然后模糊另一个控件使其淡入)。也可使用像素着色器创建给人留下深刻印象的用户交互效果(例如,当用户将鼠标移动到按钮上时增加按钮上的辉光)。最后为像素着色器的属性应用动画,就像为其他内容应用动画一样容易。

  下图显示的页面是基于在前面给出的旋转按钮示例构建的。该例包含一系列按钮,并且当用户将鼠标移动到其中某个按钮上时,关联并开始动画。区别在于这个示例中的动画不是旋转按钮,而将模糊半径减少至0。结果是移动鼠标时,最近的按钮骤然轻快地变得清晰。

该例的代码和旋转按钮示例中的代码相同。需要为每个按钮提供BlurEffect对象而不是RotateTransform对象:

<Setter Property="Effect">
     <Setter.Value>
            <BlurEffect Radius="10"></BlurEffect>
     </Setter.Value>
</Setter>

 还需要相应地修改动画:

<EventTrigger RoutedEvent="Button.MouseEnter">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="Effect.Radius"
         To="0" Duration="0:0:0.4"></DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>

                <EventTrigger RoutedEvent="Button.MouseLeave">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="Effect.Radius" To="10"
        Duration="0:0:0.2"></DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>

本实例完整XAML标记:

<Window x:Class="Animation.BlurringButtons"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="BlurringButtons" Height="300" Width="300" WindowStartupLocation="CenterScreen">
    <Window.Resources>

        <Style TargetType="{x:Type Button}">
            <Setter Property="HorizontalAlignment" Value="Center"></Setter>
            <Setter Property="RenderTransformOrigin" Value="0.5,0.5"></Setter>
            <Setter Property="Padding" Value="20,15"></Setter>
            <Setter Property="Margin" Value="2"></Setter>
            <Setter Property="Effect">
                <Setter.Value>
                    <BlurEffect Radius="10"></BlurEffect>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <EventTrigger RoutedEvent="Button.MouseEnter">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="Effect.Radius"
         To="0" Duration="0:0:0.4"></DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>

                <EventTrigger RoutedEvent="Button.MouseLeave">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <DoubleAnimation Storyboard.TargetProperty="Effect.Radius" To="10"
        Duration="0:0:0.2"></DoubleAnimation>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>

            </Style.Triggers>
        </Style>

    </Window.Resources>
    <StackPanel Margin="5">
        <Button>One</Button>
        <Button>Two</Button>
        <Button>Three</Button>
        <Button>Four</Button>
        <TextBlock Name="lbl" Margin="5"></TextBlock>
    </StackPanel>
</Window>

为反向使用相同的方法来突出显示按钮。例如,可使用应用辉光效果的像素着色器突出显示鼠标在其上悬停的按钮。

WPF中如何利用Style样式的EventTrigger和ColorAnimation为控件实现鼠标滑过或按下时改变背景颜色 <Border BorderThickness="0 1 0 1" BorderBrush="#D0CFD4"> <Border.Style> <Style TargetType="{x:Type Border}"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> 阅读详情

相关推荐

WPF中的渐变色动画

在上面的示例中,我们创建了一个名为"GradientAnimationStoryboard"的故事板(Storyboard),并在故事板中定义了一个颜色动画(ColorAnimation)。颜色动画的属性包括起始颜色(From)、结束颜色(To)、持续时间(Duration)、自动反转(AutoReverse)和重复行为(RepeatBehavior)。在上面的示例中,我们从红色(Red)过渡到蓝色(Blue),持续时间为2秒,并设置了自动反转和无限重复。首先,我们需要在XAML文件中定义一个渐变色动画。

HsvvDatabase的博客 861

【WPF动画】

示例代码1示例代码2:使用 `Storyboard` 组合多个动画代码解释应用场景动画类描述使用示例适用场景用于为double类型的属性(如WidthHeight等)创建动画。控件大小的变化、透明度的渐变等。用于为Color类型的属性(如BackgroundForeground等)创建动画。背景色、前景色的渐变效果。用于为Point类型的属性(如CenterPosition等)创建动画。控件位置的变化、路径动画。用于为Thickness类型的属性(如MarginPadding等)创建动画。

zsr154278963的博客 2052

WPF进阶 | WPF 数据绑定进阶:绑定模式、转换器与验证

WPF进阶 | WPF 数据绑定进阶:绑定模式、转换器与验证,在 WPF 应用程序开发中,数据绑定是连接用户界面(视图)与应用程序数据(模型)的桥梁。它使得视图能够自动反映数据的变化,反之亦然,极大地提高了开发效率和代码的可维护性。基础的数据绑定知识是开发者的必备技能,而深入理解绑定模式、掌握转换器的使用以及实现有效的数据验证,则是构建复杂且健壮的 WPF 应用程序的关键。本文将深入探讨这些进阶主题,帮助开发者充分发挥 WPF 数据绑定的强大功能。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 2308

WPF前台动画Animation

以下是简单的按钮动画,当鼠标移过按钮及触发动画效果: <Button x:Name="test" Content="text" Height="50" Width="100" Background="Red"> <Button.Triggers > <EventTrigger RoutedEvent="Button.MouseMove"> <BeginStoryboard

990

VirtualPetWPF项目实战:2018年Spring的WPF虚拟宠物开发

WPF(Windows Presentation Foundation)是微软公司推出的一个用于构建Windows客户端应用程序的用户界面框架。它允许开发者创建具有丰富视觉体验的应用程序。WPF采用了XAML(可扩展应用程序标记语言)与后台的C#或其他.NET支持的语言相结合的方式来设计用户界面,这使得界面设计与后端逻辑的分离变得更加清晰。开发者不仅可以处理现有的UI事件,还可以根据需要创建自定义事件。创建自定义事件需要定义一个委托和一个事件。以下是一个简单的自定义事件的示例:set;

weixin_32836713的博客 1064

构建互动式WPF抽奖器:从设计到实现

WPF(Windows Presentation Foundation)是微软推出的一种用于构建Windows客户端应用程序的UI框架。WPF提供了一种新的方式来设计和开发应用程序,它将界面设计和业务逻辑分离,从而使得开发更加高效。WPF的亮点在于其丰富的控件库、矢量图形支持、样式和模板以及强大的数据绑定功能。XAML(可扩展应用程序标记语言)是一种用于定义WPF用户界面的标记语言。通过XAML,开发者可以以声明性的方式描述用户界面,XAML的语法清晰,易于理解,使得设计师和开发者可以更好地协作。

weixin_30598047的博客 792

【WPF学习】第五十三章 动画类型回顾

  创建动画面临的第一个挑战是为动画选择正确的属性。期望的结果(例如,在窗口中移动元素)与需要使用的属性(在这种情况下是Canvas.Left和Canvas.Top属性)之间的关系并不总是很直观。下面是一些指导原则:   如果希望使用动画来使元素显示和消失,不要使用Visibility属性(该属性只能在完全可见和完全不可见之间进行切换)。应改用Opacity属性淡入或淡出元素。   如果希望动态改变元素的位置,可考虑使用Canvas面板。它提供了最直接的属性(Canvas.Left及Canvas.Top).

深蓝旭的博客 269

SAP高级外币评估_FINS_FXV_S4 2022 OP

摘要:S/4HANA 2022 On-Premise中的高级外币评估(FINS_FXV)取代了经典外币估值(FAGL_FCV),提供更优化的财务结算功能。主要创新包括:增量发布逻辑、简化账户配置、行项目级估值可见性等。该功能支持IFRS9等会计准则,通过会计原则(Accounting Principle)进行配置,需完成财务报表版本定义、语义标记分配等必要设置。系统演示展示了从汇率维护(FB60/MIRO)、测试运行到最终过账(FB03)的完整流程,能自动计算并过账汇率差异。高级外币评估简化了期末结算操作,

yanzibing99的博客 1258

Wpf_特效动画

Wpf_特效动画 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 开发工具与关键技术:Visual Studio 2015* SQL Server 作者: 撰写时间:2019年07月17日 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~...

weixin_44564948的博客 528

Linux 命令之 locale -- 设置和显示程序运行的语言环境

文章目录命令介绍locale 设置规则使用详解(一)查看当前 locale 设置(二)查看当前系统所有可用 locale(三)设置系统的 locale 命令介绍 locale 是 Linux 系统中多语言环境的设置接口,在 Linux 中,使用 locale 命令来设置和显示程序运行的语言环境,locale 会根据计算机用户所使用的语言,所在国家或者地区,以及当地的文化传统定义一个软件运行时的语言环境。 通过 locale 来设置程序运行的不同语言环境,locale 由ANSI C提供支持。locale 的

liaowenxiong的博客 3万+

【TCAX相关】Python 官方手册下载页面(中文+英文)

Python 官方手册下载页面(中文+英文) 中文: https://docs.python.org/zh-cn/3.8/archives/ https://docs.python.org/zh-cn/3.6/archives/ 英文: https://www.python.org/doc/versions/ https://docs.python.org/3/archives/ https://www.python.org/ftp/python/doc/ ...

Seekladoom的博客 1010

WPF基础知识汇总一(阴影,模糊)

渲染变换():把按钮旋转90度,周围的控件会遮挡当前按钮布局变换() :把按钮旋转90度,周围的控件会自动让出空间,整体布局会变。需要其他控件“让位置” →只是自己“变着玩” →动态变换案例径向渐变画刷画刷动画,矩形引入画刷绑定按钮,点击按钮矩形按照指定的方式动作。

weixin_45499919的博客 272

单细胞轨迹分析实战:基于Monocle和CytoTRACE的细胞分化潜能与状态解析

本文提供了基于Monocle和CytoTRACE的单细胞轨迹分析实战指南。通过乳腺癌数据集,详细演示了从数据准备、伪时序分析、细胞分化潜能评估到分支点功能挖掘的全流程。结合两种工具的优势,能有效解析细胞状态动态演变,为发育和疾病研究提供关键见解。

weixin_29070861的博客 477

基于 WPF 平台使用纯 C# 制作流体动画

通过纯 C# 在 WPF 平台上制作流体动画,我们深入探索了 WPF 动画机制和流体模拟算法。从基础的动画回顾到复杂的流体模拟实现,每一步都充满挑战与乐趣。希望这篇文章能帮助大家在 WPF 开发中创造出更具创意和交互性的流体动画效果,在未来的开发中,大家可以尝试结合更复杂的物理模型和图形渲染技术,进一步拓展流体动画的表现力。

让每一个想学习编程的人,都能学会,都能看懂,看了都有收获! 1839

【机器学习(一)】从零到一:用sklearn构建你的第一个机器学习项目

本文为机器学习新手提供了一个完整的端到端实战指南。通过使用Python的scikit-learn库,以经典的鸢尾花数据集为例,详细演示了从环境搭建、数据探索、预处理、模型训练与评估,到超参数调优和模型保存的全流程。文章旨在帮助读者快速构建第一个机器学习项目,掌握核心工作流和工程实践。

weixin_29070861的博客 467

【实战】Python 携程酒店价格实时抓取爬虫项目全解析

摘要:本文介绍了一个基于Python的携程酒店价格实时抓取系统开发方案。系统采用Requests、BeautifulSoup和Selenium等技术栈,实现了多城市、多日期的酒店数据采集,包括价格、评分、位置等关键信息。通过请求头伪装、IP代理、随机等待等反爬策略,有效应对携程的反爬机制。系统支持数据清洗、去重和CSV/Excel导出,并提供了多线程优化、代理池集成等进阶方案。本文详细阐述了技术原理、代码实现和优化策略,同时强调了数据采集的合法合规性,为旅游行业数据分析提供了可靠的数据获取方案。

2503_91057718的博客 2604

如何学习 WPF 详细教程

一、WPF 技术介绍 二、学习前的准备工作 三、学习时的具体操作 四、如何巩固学习 五、WPF 知识总结 1、C# 编程语言 2、XAML 标记语言 3、数据绑定 5、动画和转换

不迁怒,不贰过。小知识,大智慧。 1万+

华为OD机试真题2025双机位C卷 Java&Go 实现【卡牌游戏】

小明正在尝试一种新的牌游戏。游戏规则只如下:首先,小明拿到一张写有数字m的牌。 然后,他会拿到另外n张牌,上面分别写有不同的数字,牌排成一排。小明的目标是从这排牌中找到一串连续的牌,这些牌上数字的总和可以被 m整除。你的任务是判断小明是否可以完成这个目标。

MISAYAONE的博客 392

WPF教学视频详解|WPF NavigationBar 如此丝滑的动画竟然这么简单?!GitHub源代码 |编程原视频已上传

WPF 应用程序传统上通过菜单构成将多个界面连接并集成到一个程序中。因此,菜单或称为导航的技术是 WPF 的核心实现之一。由于这与项目的架构(设计)直接相关,如果更仔细地实现这一技术,也可以预期项目的质量会得到显著提升。 此控件虽然在移动设备上以特殊设计和动画为特点,但如果在 WPF 中使用 ListBox 和动画技术,也可以实现结构优良且优雅的效果。此外,像 AvaloniaUI、Uno、OpenSilver、MAUI 等跨平台工具也可以用类似方式实现,因此希望这一项目能够在各种平台上得到研究和应用。

VickyQu214的博客 1189

LVGL misc timer 定时器(lv_timer.c)

定时器机制是LVGL中非常重要的一项功能,它承载了LVGL的延时任务执行,周期任务执行,时序任务执行等,可以说理解定时器的设计就一定程度上理解发LVGL的任务调度机制。

Bigan(安)的博客 4729

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

WPF弹幕控件源码讲解与踩坑回顾

基于c#写的WPF弹幕控件,近乎完美,该控件简单,适用性强,只有一个添加弹幕的方法。该控件考虑了,效率性能,重复利用等问题。目前只有从左往右一个方向,不过控件设计之初考虑到诸如此类的问题,因此有需要的再进行二次开发即可,代码的可阅读性还是蛮高的。下载地址https://download.youkuaiyun.com/download/shizu11zz/10983463,内含源码。 接下来将要根据源码来解...

shizu11zz的博客 1056

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

【C#】学习WPF的生产管理平台回顾与总结

花了一周时间跟着B站的学习了如何用WPF制作一个生产管理平台上位机软件,学习完了,在此总结涉及到的相关知识.

一只爱做笔记的码农 1196

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

简单分析WPF是什么

<br />WPF是什么?对于一个不是长时间接触开发的人来说可能不太了解这一词汇。WPF被很多中国开发人员戏称为“我佩服”。它确实是一个功能比较强大的图形界面处理工具。<br />先让我们来回顾一下微软的各种界面显示技术:<br />User32:它提供了最基本的Windows界面,包括按钮,编辑框和其他UI元素。但是,User32缺乏的是图形图像的绘制功能,无法对屏幕实现自定义的绘制。<br />GDI (Graphics device interface):- 为了提供图形图像的绘制功能,微软在User

fsqcy的专栏 611

WPF介绍

转载:http://msdn.microsoft.com/zh-cn/library/aa970268.aspx

都芳飞龙的专栏 1700

WPF的发展历程

架构愿景实现:WPF最初设计的分离关注点、声明式UI、矢量图形等核心理念,如今已被广泛接受并影响了众多现代UI框架。企业应用基石:在企业应用开发领域,WPF因其稳定性、表现力和丰富功能,仍然是首选技术之一。专业领域深耕:在金融、医疗、工业控制等专业领域,WPF的高性能图形和数据处理能力难以替代。设计方法论影响:MVVM模式从WPF发展而来,如今已成为众多现代UI框架采用的架构模式。技术生态持续进化:开源转型后,WPF生态系统获得了新的活力,不断适应现代开发需求。

冰茶的博客 1758

深入浅出WPF(1)——什么是WPF

深入浅出WPF(1)——什么是WPF  小序:  Hi,大家好!几乎两个月没有写技术文章了。这两个月,我在学习WPF。回顾一下两个月的学习历程,有两个感觉——第一,WPF是一项非常实用又简单易学的东西,它将成为未来MS平台上快速开发的主流趋势;第二,WPF的学习比较讲求路径,如果没有一个比较好的路径,学习起来可能比较慢,主要原因是它像是一种ASP.NET与Windows Forms

水之真谛 4万+
上一篇: WPF 透明
下一篇: WPF 行为
西飘客
博客等级 码龄12年 170粉丝 214原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值