日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

【WPF学习笔记】[转]周银辉之WPF中的动画 晓风影天之wpf动画——new PropertyPath属性链...

發布時間:2023/12/10 asp.net 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【WPF学习笔记】[转]周银辉之WPF中的动画 晓风影天之wpf动画——new PropertyPath属性链... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

(一)WPF中的動畫

?

動畫無疑是WPF中最吸引人的特色之一,其可以像Flash一樣平滑地播放并與程序邏輯進行很好的交互。這里我們討論一下故事板。

在WPF中我們采用Storyboard(故事板)的方式來編寫動畫,為了對Storyboard有個大概的印象,你可以粘貼以下代碼到XamlPad來查看效果:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"WindowTitle="Storyboards Example"><StackPanel Margin="20"><Rectangle Name="MyRectangle"Width="100"Height="100"><Rectangle.Fill><SolidColorBrush x:Name="MySolidColorBrush" Color="Blue" /></Rectangle.Fill><Rectangle.Triggers><EventTrigger RoutedEvent="Page.Loaded"><BeginStoryboard><Storyboard RepeatBehavior="Forever" AutoReverse="True"><DoubleAnimation Storyboard.TargetName="MyRectangle"Storyboard.TargetProperty="Width"From="100" To="200" Duration="0:0:1" /> </Storyboard></BeginStoryboard></EventTrigger></Rectangle.Triggers></Rectangle> </StackPanel> </Page>

在介紹Storyboard之前應該先了解Animation
Animation提供一種簡單的“漸變”動畫,我們為一個Animation指定開始值和一個結束值,并指定由開始值到達結束值所需的時間,便可形成一個簡單的動畫。比如我們指定長方形的寬度由100變化到200,所需時間為1秒,很容易想像這樣的動畫是什么樣的,而它對應的Xaml代碼如下:

<DoubleAnimation Storyboard.TargetName="MyRectangle"Storyboard.TargetProperty="Width"From="100" To="200" Duration="0:0:1" />

將它翻譯成C#代碼則如下:

DoubleAnimation myDoubleAnimation = new DoubleAnimation();myDoubleAnimation.From = 100;myDoubleAnimation.To = 200;myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Rectangle.WidthProperty));

代碼里我們定義了一個DoubleAnimation,并指定了它的開始值和結束值以及它由開始值到達結束值所需的時間。至于后面兩句,它們是用來將Aniamtion與指定的對象和指定的屬性相關聯,等會我們將介紹。
注意到,這里我們使用的是DoubleAnimation,因為我們所要變化的是數值。那么如果我們要變化顏色是不是就用ColorAnimation了呢,對,其實出了這些之外還有PointAnimation等等,并且你可以實現IAnimatable接口來實現自定義版本的Animation。關于這些你可以參見System.Windows.MediaAniamtion名字空間.

但值得注意的是并非每個屬性都能夠使用Animation,它必須滿足以下條件:
1,它必須是Dependency Property
2,它所在類必須繼承于DependencyObject,必須實現了IAnimatable接口.
3,必須有類型一致的Animation Type(即Color類型使用ColorAniamtion,Point類型使用PointAnimation等)

一個簡單的Animation定義了一個簡單的動畫,很容易想到的是,如果若干個Animation同時作用于一個對象,那么這個對象不就可以表現復雜的動畫了嗎,對,這就是Storyboard

Storyboard可以看做是Animation的容器,它包含了若干的簡單動畫來完成一個復雜動畫。
參考以下代碼:

<!-- This example shows how to animate with a storyboard.--> <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"WindowTitle="Storyboards Example"><StackPanel Margin="20"><Rectangle Name="MyRectangle"Width="100"Height="100"><Rectangle.Fill><SolidColorBrush x:Name="MySolidColorBrush" Color="Blue" /></Rectangle.Fill><Rectangle.Triggers><EventTrigger RoutedEvent="Page.Loaded"><BeginStoryboard><Storyboard RepeatBehavior="Forever" AutoReverse="True"><DoubleAnimation Storyboard.TargetName="MyRectangle"Storyboard.TargetProperty="Width"From="100" To="200" Duration="0:0:1" /> <ColorAnimation Storyboard.TargetName="MySolidColorBrush"Storyboard.TargetProperty="Color"From="Blue" To="Red" Duration="0:0:1" /> </Storyboard></BeginStoryboard></EventTrigger></Rectangle.Triggers></Rectangle> </StackPanel> </Page>

這里我們的Storyboard定義了DoubleAnimation來變化矩形的寬度,并定義了ColorAnimation來變化矩形的顏色。

至此,你已經可以編寫絢麗的WPF動畫了,并推薦你下載Expression Blend來制作WPF動畫.



但你會發現使用XAML標記的方式來編寫動畫雖然很簡單,但缺乏了C#等程序設計語言的靈活性,比如我們的矩形動畫中矩形的寬度是由后臺邏輯計算出來的變量值,我們的動畫將如何編寫呢,這時我更喜歡使用C#的方式來編寫動畫,雖然這所需的代碼量更大.
以下重點介紹如何用C#編寫動畫,并且這更助于你理解Storyboard是如何工作的。

參考以下代碼:

this.Name = "PageMain";myRectangle.Name = "MyRectangle"; NameScope.SetNameScope(this, new NameScope()); this.RegisterName(myRectangle.Name, myRectangle);DoubleAnimation myDoubleAnimation = new DoubleAnimation();myDoubleAnimation.From = 100;myDoubleAnimation.To = 200;myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Rectangle.WidthProperty));Storyboard myStoryboard = new Storyboard();myStoryboard.Children.Add(myDoubleAnimation);this.Loaded += delegate(object sender, MouseEventArgs e){myStoryboard.Begin(this);};

其中:

?

??????????? DoubleAnimation?myDoubleAnimation?=?new?DoubleAnimation();
????????????myDoubleAnimation.From?=?100;
????????????myDoubleAnimation.To?=?200;
????????????myDoubleAnimation.Duration?=?new?Duration(TimeSpan.FromSeconds(1));
定義了一個DoubleAniamtion,并指定了它的開始值和結束值以及所需的時間.
Storyboard.SetTargetName(myDoubleAnimation,?myRectangle.Name);設置myDoubleAniamtion的作用對象是"myRectangle",注意到傳入的第二個參數是一個字符串myRectangle.Name,那么我們的程序怎么知道"myRectangle"這個字符串就是指我們的矩形對象myRectangle呢,這里存在一個名稱與對象的映射,即我們的"myRectangle"映射到矩形對象myRectangle,為了構造這個映射我們涉及到了NameScope(名字域)這個概念.
??????????? NameScope.SetNameScope(this,?new?NameScope());??????????????????????
????????????this.RegisterName(myRectangle.Name,?myRectangle);
上面的代碼中,this設置了一個名字域,myRectagle向這個名字域注冊了自己的名字,這樣我們的程序就可以通過this的名字域來查找到myRectangle與"myRectangle"之間的映射關系了,關于NameScope可以參見MSDN?WPF Namescopes主題.
為了讓myDoubleAnimation知道它所作用的屬性是誰,我們使用Storyboard.SetTargetProperty(myDoubleAnimation,?new?PropertyPath(Rectangle.WidthProperty));語句來將Aniamtion與屬性關聯起來,其中PropertyPath中指定要作用的對象所對應的DependencyProperty.
然后我們將定義好的myDoubleAniamtion添加到myStoryboard的Children中去.最后就可以通過調用Storyboard的Begin(FrameworkElement)方法來開始我們的動畫.

Begin方法的另一個重載形式是public?void?Begin?(FrameworkContentElement?containingObject,bool?isControllable),第二個參數表明我們的storyboard是否是可控的,如果可控的話,我們可以像控制播放器一樣控制來控制storyboard,關于控制Storyboard請參考Storyboard類中的Pause,Seek等方法.

至此也許我們會認為這些知識足以應付簡單的動畫了,現在讓我們一起設計一個簡單的動畫,也許會發現些問題.

假設我們的界面中存在一個Button對象button1,我們設計一個簡單的動畫讓它在窗口中的x坐標從0連續變化到100,然后在從100變化到0,如此重復.也許我們會編寫如下的代碼:

this.button1.Name = "button1";this.Name = "window1";NameScope.SetNameScope(this, new NameScope());this.RegisterName(this.button1.Name, this.button1);DoubleAnimation xAnimation = new DoubleAnimation();xAnimation.From = 0;xAnimation.To = 100;xAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));Storyboard story = new Storyboard();story.AutoReverse = true;story.RepeatBehavior = RepeatBehavior.Forever;story.Children.Add(xAnimation);Storyboard.SetTargetName(xAnimation, this.button1.Name);Storyboard.SetTargetProperty(xAnimation, ???);

但當我們編寫到Storyboard.SetTargetProperty(xAnimation,????);時發現似乎不知道將我們的xAniamtion關聯到哪個屬性.似乎Button中沒有用來控制X坐標的DependencyProperty.但通過研究后發現(你可以通過ExpressionBlend自動生成的XAML代碼來發現這些信息),如果我們將button1的RenderTransform設置為TranslateTransform,然后可以通過TranslateTransform的XProperty屬性來更改button1的X坐標.注意到,我們并不是像以前一樣直接關聯到Button的某個屬性(比如先前的WidthProperty),而是通過其RenderTransformProperty屬性的XProperty來間接關聯的,這中方式叫做"屬性鏈"(PropertyChain).
參考下面的代碼:

DependencyProperty[] propertyChain = new DependencyProperty[]{Button.RenderTransformProperty,TranslateTransform.XProperty};Storyboard.SetTargetProperty(xAnimation, new PropertyPath("(0).(1)", propertyChain));

為了構造PropertyChain,我們先定義一個DependencyProperty的數組,注意數組的元素是怎么來的,它按照屬性鏈的"鏈條"關系依次書寫,直到到達我們最終要修改的屬性,(由于我們是通過將RenderTransformProperty設置為TranslateTransform類型,所以第二個元素是TranslateTransform.XProperty),簡單地說就是(類型1.屬性1,類型2.屬性2,....類型n.屬性n),其中類型i是屬性i-1的類型或可以與之轉換的類型.
這樣我們的代碼就演化如下:

this.button1.RenderTransform = new TranslateTransform();this.button1.Name = "button1";this.Name = "window1";NameScope.SetNameScope(this, new NameScope());this.RegisterName(this.button1.Name, this.button1);DoubleAnimation xAnimation = new DoubleAnimation();xAnimation.From = 0;xAnimation.To = 100;xAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));DependencyProperty[] propertyChain = new DependencyProperty[]{Button.RenderTransformProperty,TranslateTransform.XProperty};Storyboard story = new Storyboard();story.AutoReverse = true;story.RepeatBehavior = RepeatBehavior.Forever;story.Children.Add(xAnimation);Storyboard.SetTargetName(xAnimation, this.button1.Name);Storyboard.SetTargetProperty(xAnimation, new PropertyPath("(0).(1)", propertyChain));story.Begin(this);

注意:如果你收到關于PropertyChain的運行時錯誤或動畫沒有效果,那么你應該初始化button的RenderTransform屬性,所以我們添加了this.button1.RenderTransform = new TranslateTransform();語句.

=======================================================================================================================

)wpf動畫——new PropertyPath屬性鏈

?

在wpf中我們常用storyboard故事板裝載很多的動畫處理Animation,我們需要用Storyboard.SetTarget設置操作的對象,需要用Storyboard.SetTargetProperty設置操作對象的操作屬性PropertyPath,本例將說明一種操作屬性PropertyPath的便利方法:

1.新建一個wpf應用程序,簡單修改一下xaml展示如下:

<Window x:Class="WpfApplication48.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="MainWindow" Height="350" Width="525"><Grid><Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" /></Grid> </Window>

2.后臺cs修改如下(效果:點擊button,button的橫坐標x由12到300,播放過程動畫):

/// <summary>/// MainWindow.xaml 的交互邏輯/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}private void button1_Click(object sender, RoutedEventArgs e){this.button1.RenderTransform = new TranslateTransform();Storyboard sb = new Storyboard();DoubleAnimation da = new DoubleAnimation();da.From = 12;da.To = 300;da.Duration = TimeSpan.FromSeconds(3);sb.Children.Add(da);DependencyProperty[] propertyChain = new DependencyProperty[]{Button.RenderTransformProperty,TranslateTransform.XProperty};Storyboard.SetTarget(da, this.button1);Storyboard.SetTargetProperty(da, new PropertyPath("(0).(1)", propertyChain));sb.Completed += new EventHandler((object sender1, EventArgs e1) => { MessageBox.Show("completed"); });sb.Begin();}}

一般我們在寫到Storyboard.SetTargetProperty時遇到new PropertyPath,

如果是簡單的屬性,例如Button.WidthProperty,我們可以直接new PropertyPath(Button.WidthProperty)達到目的,
但如果你發現你需要操作到的屬性無法在Button中直接'.'出來,就需要用到上例用到的屬性鏈方法:

首先定義一個屬性鏈:

DependencyProperty[] propertyChain = new DependencyProperty[]{Button.RenderTransformProperty,TranslateTransform.XProperty};

屬性鏈的寫法,定義一個DependencyProperty屬性的數組,該數組中的元素均是Property屬性,且按照從屬關系先后排列,例如上例中,我們需要先將button的RenderTransform設置為TranslateTransform,然后通過TranslateTransform的XProperty來更改button的x坐標,

當然,別忘了初始化button的RenderTransform屬性= new TranslateTransform(),否則動畫將沒有效果。

?

以上未經博主同意轉載,敬請原諒。

轉載于:https://www.cnblogs.com/Owen-ET/p/5981660.html

總結

以上是生活随笔為你收集整理的【WPF学习笔记】[转]周银辉之WPF中的动画 晓风影天之wpf动画——new PropertyPath属性链...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。