c#學(xué)習(xí)之30分鐘學(xué)會(huì)XAML
1.狂妄的WPF
相對(duì)傳統(tǒng)的Windows圖形編程,需要做很多復(fù)雜的工作,引用許多不同的API。例如:WinForm(帶控件表單)、GDI+(2D圖形)、DirectX API(3D圖形)以及流媒體和流文檔等,都需要不同的API來構(gòu)建應(yīng)用程序。
WPF就是看著上面的操作復(fù)雜和不爽,自己決定做老大,想用DirectX技術(shù)涵蓋一切,于是想要將上述的東西全部融合到自身,減少?gòu)?fù)雜度,讓編程變得爽起來的技術(shù)。
而不可否認(rèn)的是,WPF雖然很狂妄,但是這種技術(shù)里面還是有不少的可圈可點(diǎn)的東西。而支持WPF狂妄的資本,則就是和它后臺(tái)代碼可以前后分離的XAML技術(shù)。下面用30分鐘時(shí)間說一下XAML。
2.什么是XAML
一個(gè)界面程序的核心,無(wú)疑就是界面和后臺(tái)代碼,而xaml就是微軟為構(gòu)建應(yīng)用程序界面而創(chuàng)建的一種描述性語(yǔ)言,也就是說,這東西是搞界面的。
先上一段xaml代碼:
<Window x:Class='MyXaml.Window1' xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' Title='MyXaml' Height='150' Width='300' > <Grid> <Grid.RowDefinitions> <RowDefinition Height='30'/> <RowDefinition Height='30'/> <RowDefinition Height='30'/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width='Auto'/> <ColumnDefinition Width='*'/> </Grid.ColumnDefinitions> <TextBlock Grid.Column='0' Grid.Row='0' FontWeight='Bold' Text='姓名:' Width='30'/> <TextBlock Grid.Column='0' Grid.Row='1' FontWeight='Bold' Width='30'>性別:</TextBlock> <TextBlock Grid.Column='0' Grid.Row='2' FontWeight='Bold' Width='30' Text='年齡'></TextBlock> <TextBox Grid.Column='1' Grid.Row='0' FontWeight='Bold' Width='100' /> <TextBox Grid.Column='1' Grid.Row='1' FontWeight='Bold' Width='100'/> <TextBox Grid.Column='1' Grid.Row='2' FontWeight='Bold' Width='100'/> </Grid> </Window>
上述xaml是我設(shè)計(jì)了一個(gè)三行兩列的界面,運(yùn)行之后顯示如下:
在此,我沒有寫一行c#代碼,但是它竟然可以運(yùn)行,所以也可以說它也是一種編程語(yǔ)言。只不過它更關(guān)注界面上面的東西而已。
那么它的運(yùn)行是如何產(chǎn)生的?下面看幾個(gè)東西:
x:Class='MyXaml.Window1' ——利用class特性指定c#類名(后臺(tái)c#代碼)
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml——這表示利用x代替XAML的命名空間。用于包含特定的關(guān)鍵字和System.Windows.Markup中類型的子集。
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation——另一個(gè)命名空間。映射諸多wpf.net命名空間(system.windows.xxx,是個(gè)一對(duì)多的映射,主要封裝了三個(gè)程序集中,WindowsBase.dll、Presentation.dll和PresentationFramework.dll)
2.1 啟動(dòng)
程序啟動(dòng)的地方,其實(shí)是在程序的App.xaml文件里面:
<Application x:Class='MyXaml.App' xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' StartupUri='Window1.xaml'> <Application.Resources> </Application.Resources> </Application>
看下面這句:
StartupUri='Window1.xaml'
這個(gè)就是程序的入口點(diǎn),運(yùn)行程序之后,我們就將window1顯示在了顯示屏上。
3.XAML語(yǔ)法概述
上述xaml中,顯示的一個(gè)核心布局就是以下這些代碼:
<Grid> <Grid.RowDefinitions> <RowDefinition Height='30'/> <RowDefinition Height='30'/> <RowDefinition Height='30'/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width='Auto'/> <ColumnDefinition Width='*'/> </Grid.ColumnDefinitions> <TextBlock Grid.Column='0' Grid.Row='0' FontWeight='Bold' Text='姓名:' Width='30'/> <TextBlock Grid.Column='0' Grid.Row='1' FontWeight='Bold' Width='30'>性別:</TextBlock> <TextBlock Grid.Column='0' Grid.Row='2' FontWeight='Bold' Width='30' Text='年齡'></TextBlock> <TextBox Grid.Column='1' Grid.Row='0' FontWeight='Bold' Width='100' /> <TextBox Grid.Column='1' Grid.Row='1' FontWeight='Bold' Width='100'/> <TextBox Grid.Column='1' Grid.Row='2' FontWeight='Bold' Width='100'/> </Grid>
1、看Grid控件,這個(gè)在wpf中是一個(gè)布局控件,就跟將窗體設(shè)置單元格差不過,可以依據(jù)它的row和column屬性來設(shè)置行和列。上述設(shè)置了一個(gè)三行兩列的布局。
2、看TextBlock和TextBox控件,這些都是一些顯示控件,一個(gè)顯示條和一個(gè)文本框,wpf中除此之外,還有許多的控件。
首先需要再確認(rèn)的一點(diǎn),那就是在C#中一切皆對(duì)象。如此一來,也就好理解了。
在XAML中的這些形形色色的控件其實(shí)就是一個(gè)個(gè)的類,我們應(yīng)用了他們就相當(dāng)于是應(yīng)用了一個(gè)個(gè)的對(duì)象,而他們之中定義的一些width、height等屬性,就是這些類中封裝的一些屬性字段。
當(dāng)然,像上面TextBox和TextBlock中的Grid.Column='1' Grid.Row='2'等屬性,其實(shí)并不屬于這兩個(gè)類中的屬性和字段。
而使得他們具備這樣屬性的,無(wú)疑就是外面的Grid布局控件賦予的,而在WPF中這樣的功能實(shí)現(xiàn)叫做附加屬性,是依賴屬性的一個(gè)特殊的用法。關(guān)于依賴屬性,在以后會(huì)詳細(xì)的討論。
第一個(gè)總結(jié)
WPF的XAML語(yǔ)法其實(shí)可以理解成另外一種形式的編程語(yǔ)言,其語(yǔ)法表現(xiàn)形式和XML類似,但是更嚴(yán)謹(jǐn)和更要求準(zhǔn)確性。
XAML主要包括布局和控件,以此來構(gòu)建各種形態(tài)的應(yīng)用程序,除此之外,其中還有許多新的強(qiáng)大的東西,使得它更靈活和方便,例如依賴屬性。
3.1 布局
WPF中的布局常用的主要包括五種:Canvas、Grid、StackPanel、DockPanel和WrapPanel。下面分別說一下這五種布局控件的使用。
1、 Canvas
要說Canvas,先看以下的xaml代碼:
<Canvas> <Button Name='btn1' Height='100' Width='100' Content='btn1' Margin='10'/> <Button Name='btn2' Height='100' Width='100' Content='btn2' Margin='10'/> </Canvas>
然后,查看在畫布Canvas上面生成的畫面,情況如下:
為什么不顯示btn1?因?yàn)閮蓚€(gè)button重疊了起來,只顯示最上面的控件(越接近結(jié)束標(biāo)簽 </Canvas>的控件,如果兩個(gè)button的位置顛倒一下,顯現(xiàn)出來的就是btn1).
Canvas的布局基本就和之前的Winform一致了,都是以左上角為中心,按照上下距離左上角的坐標(biāo)為標(biāo)準(zhǔn)的。如果想要改變button的位置,就要給button控件設(shè)置Canvas.Left、 Canvas.Top、Canvas.Bottom 和Canvas.Right這四個(gè)屬性。
所以Canvas得重點(diǎn)在絕對(duì)布局,對(duì)要求不太高的界面和比較固定的界面可以用這樣的方式拖拽控件布局。
2、 Grid
WPF窗體程序的默認(rèn)布局就是一個(gè)Grid,先看如下代碼:
<Grid> <Button Name='btn1' Height='100' Width='100' Content='btn1' Margin='10'/> <Button Name='btn2' Height='100' Width='100' Content='btn2' Margin='10'/> </Grid>
看到這里,你也許會(huì)說,這不是和上面的Canvas一樣嗎?但是真的一樣嗎?他們的窗體如下所示:
相信你一定看出來了,不錯(cuò),和Canvas不同,Grid窗體默認(rèn)的顯示是以中心為基準(zhǔn)的,不像Canvas布局是以左上角為標(biāo)準(zhǔn)。
那么Grid布局有什么樣的好處呢?看下面這些代碼:
<Grid> <Grid.RowDefinitions> <RowDefinition Height='*'/> <RowDefinition Height='*'/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width='*'/> <ColumnDefinition Width='*'/> </Grid.ColumnDefinitions> <Button Name='btn1' Height='40' Width='40' Content='btn1' /> <Button Grid.Row='1' Grid.Column='1' Name='btn2' Height='40' Width='40' Content='btn2' /> </Grid>
然后在看看生成的窗口:
相信你一定可以看明白,知道Grid是把窗體分成了一塊塊的網(wǎng)格,而分割這個(gè)功能是通過Grid.RowDefinitions和Grid.ColumnDefinitions兩組屬性定義的,分別在其中定義了行和列,將窗體分為了幾行幾列,行的高度和列的寬度可以根據(jù)Width屬性設(shè)置。
如上圖,利用xaml定義了一個(gè)兩行兩列的Grid,并且在第0行0列放置btn1(如不顯示定義,則拖入的控件默認(rèn)放在此網(wǎng)格。),第1行1列放置了btn2.
關(guān)于網(wǎng)格屬性做以下幾個(gè)說明。
RowDefinition 表示網(wǎng)格的行,其只有一個(gè)Height屬性而沒有Width屬性,*表示該行占據(jù)窗體剩下的所有的高度,如都設(shè)為*則表示平分窗體。如上所示,你還可以讓窗體3:1,只要將兩個(gè)行定義分別設(shè)置為3*和*就可以了。
ColumnDefinition 表示網(wǎng)格的列,其中只有一個(gè)Width屬性而沒有Height屬性,*號(hào)的用法同RowDefinition的用法,不過相對(duì)RowDefinition分割窗體的高度而言,在這里*表示分割窗體的寬度。
可以說,Grid實(shí)現(xiàn)的是一種網(wǎng)格布局,這種布局是相當(dāng)強(qiáng)大的,可以并且用起來也非常靈活。
3、 StackPanel
StackPanel布局遵循的默認(rèn)原則是從窗口中間部位,從頂部開始,從上到下排列控件。先看下面代碼:
<StackPanel> <Button Name='btn1' Height='40' Width='40' Content='btn1' /> <Button Name='btn2' Height='40' Width='40' Content='btn2' /> </StackPanel>
表現(xiàn)出來的窗體如下:
如上圖所示,控件的布局默認(rèn)是豎向布局,那么如何設(shè)置控件橫向布局呢?我們只需要設(shè)置StackPanel的Orientation屬性就可以了:
Orientation='Horizontal' 橫向布局,從窗體中部,左側(cè)開始從左向右排列控件。
Orientation='Vertical'縱向布局,默認(rèn)屬性。
橫向布局的實(shí)例如下:
<StackPanel Orientation='Horizontal'> <Button Name='btn1' Height='40' Width='40' Content='btn1' /> <Button Name='btn2' Height='40' Width='40' Content='btn2' /> </StackPanel>
窗口顯示:
4、 DockPanel
Dockpanel默認(rèn)布局原則,從左中位置開始,控件依次排列,最后一個(gè)控件將剩余區(qū)域從中心填充??聪旅娲a:
<DockPanel> <Button Name='btn1' Height='40' Width='40' Content='btn1' /> <Button Height='40' Width='40' Content='btn2' /> <Button Height='40' Width='40' Content='btn2' /> <Button Height='40' Width='40' Content='btn2' /> <Button Height='40' Width='40' Content='btn2' /> <Button Height='40' Width='40' Content='btn2' /> </DockPanel>
該布局的窗體顯示如下:
同StackPanel不同,Dockpanel布局依靠的是它的四個(gè)附加在其余控件上的附加屬性,看下表:
DockPanel.Dock屬性 |
說明 |
Top |
頂部,如果設(shè)置,從中間頂部開始依照上述原則布局 |
Left |
左部,默認(rèn)布局 |
Right |
右部,如果設(shè)置,從中間右側(cè)開始依照上述原則布局 |
Button |
底部,如果設(shè)置,從中間底部開始依照上述原則布局 |
看下面實(shí)例,xaml代碼:
<DockPanel> <Button DockPanel.Dock="Bottom" Name="btn1" Height="40" Width="40" Content="btn1" /> <Button DockPanel.Dock="Bottom" Height="40" Width="40" Content="btn2" /> <Button Height="40" Width="40" Content="btn2" /> <Button Height="40" Width="40" Content="btn2" /> <Button Height="40" Width="40" Content="btn2" /> <Button Height="40" Width="40" Content="btn2" /> </DockPanel>
界面表現(xiàn)如下:
有上述描述代碼可知,此處StackPanel從底部開始布局兩個(gè)btn,在剩余的空間中(窗體上部),然后從默認(rèn)位置左部開始依次放置btn,最后一個(gè)btn將最后剩余的空間填充。
5、 WrapPanel
WrapPanel布局遵循的原則是從窗體左上角開始,多控件的自動(dòng)換行。同StackPanel一樣,它也有表示縱向和橫向的Orientation屬性??聪旅鎥aml代碼:
<WrapPanel> <Button Name="btn1" Height="40" Width="40" Content="btn1" /> <Button Height="40" Width="40" Content="btn2" /> <Button Height="40" Width="40" Content="btn2" /> <Button Height="40" Width="40" Content="btn2" /> <Button Height="40" Width="40" Content="btn2" /> <Button Height="40" Width="40" Content="btn2" /> <Button Height="40" Width="40" Content="btn2" /> <Button Height="40" Width="40" Content="btn2" /> <Button Height="40" Width="40" Content="btn2" /> <Button Height="40" Width="40" Content="btn2" /> </WrapPanel>
生成的界面如下:
由此可知,WrapPanel默認(rèn)的布局是橫向,等到右邊沒有空余,其余的控件將從第二行開始重新排列。
如果將其Orientation屬性設(shè)置Vertical那么排列將會(huì)從左上角開始,從上到下排列,下面沒有空余將會(huì)從第二行開始從上而下重新排列。如下xaml:
<WrapPanel Orientation="Vertical"> <Button Name="btn1" Height="40" Width="40" Content="btn1" /> <Button Height="30" Width="40" Content="btn2" /> <Button Height="30" Width="40" Content="btn2" /> <Button Height="30" Width="40" Content="btn2" /> <Button Height="30" Width="40" Content="btn2" /> </WrapPanel>
窗體布局如下:
由上可知,WrapPanel主要提供的功能是從窗體左上角開始,多控件的自動(dòng)換行。
第二個(gè)總結(jié):
WPF中的布局除此之外還有如下的幾種:abPanel, ToolBarOverflowPanel, ToolBarPanel, UniformGrid, VirtualizingPanel, VirtualizingStackPanel,它們都派生于Panel抽象類,內(nèi)容屬性Children可以添加多個(gè)控件。它們藉此來控制控件的布局。
3.2 控件
其實(shí)布局也是控件的一種,但是單獨(dú)講布局列出來。因?yàn)椴季衷赪PF中占據(jù)著異常重要的地位。接下來,主要說一下其他的控件,大體上,除了布局之外的控件可以分為以下的三類。
第一類:核心用戶輸入控件,用戶創(chuàng)建用戶界面的核心。其中比較常用的有Button、RadioButton、ComboBox、CheckBox、DataGrid、ListBox、ListView、TreeView、TextBlock、TextBox、Label。
第二類:窗口修飾控件,這些元素用于裝飾Window對(duì)象的框架。其中常用的有Menu、ToolBar、StatusBar、ToolTip、ProgressBar。
第三類:媒體控件,支持音頻/視頻的重放和圖像的顯示。其中比較常用的控件有Image、MediaElement、SoundPlayerAction。
下面分別說說每類控件的基本功能。
一、 核心用戶輸入控件
1、 Button、RadioButton,Button控件的基礎(chǔ)用法,主要是處理單擊Button的時(shí)候?qū)螕羰录幚淼姆绞健utton的單擊事件是通過Click特性聲明,其模式主要有三種:
Release:Button被按下然后松開時(shí)發(fā)生單擊事件
Hover: 鼠標(biāo)懸停在按鈕上方引發(fā)單擊事件
Press:當(dāng)單擊按鈕時(shí)引發(fā)單擊事件
我們可以利用Button單擊事件的模式設(shè)置我們想要的點(diǎn)擊控件的效果。
Button是內(nèi)容控件,我們可以給它的內(nèi)容設(shè)置其他的東西,比如下面的代碼,就是給一個(gè)Button按鈕設(shè)置圖片:
<Button x:Name="ImageButton" Margin="3" Grid.Row="1" HorizontalAlignment="Left"> <StackPanel Margin="1" Orientation="Horizontal" Width="620"> <Image Source="back.bmp" Stretch="UniformToFill" Width="160"/> <TextBlock Width="130" /> <TextBlock Text="圖片按鈕" Margin="1,15,1,1"/> </StackPanel> </Button>
除此之外,我們還可以給Button設(shè)置不同的樣式,使得它變得好看。涉及到了樣式、模板和觸發(fā)器,在此不過多陳述。
RadioButton和Button都是繼承自ButtonBase類,所具有的基本屬性是相同的,用法也大同小異。
2、 ComboBox控件,表示帶有下拉列表的選擇控件,通過單擊控件上的箭頭可顯示或隱藏下拉列表。用法如下:
<ComboBox> aaa </ComboBox>
其中Item表示下拉項(xiàng),可以自己設(shè)定也可以通過Binding獲得。界面編輯器在ComboBox的屬性里面有一個(gè)Items集合,用來設(shè)定ComboBox的選項(xiàng)。Binding所用到的屬性是ItemsSource屬性。效果如下圖:
ComboBox控件選中事件可以從其選中項(xiàng)的SelectedItem的屬性來binding事件處理邏輯。
3、 CheckBox控件,表示用戶可以選擇并清除的控件。其用法形式如下:
<CheckBox> Content </CheckBox>
效果如下圖所示:
CheckBox控件主要用來處理三個(gè)事件,選中事件Checked、Unchecked,以及影響外觀的Indeterminate事件,可以分別在后臺(tái)顯示三者的處理邏輯。
<CheckBox x:Name="cb1" Grid.Row="1" Margin="5,0,0,0" Content="Three-state CheckBox" IsThreeState="True" Checked="HandleCheck" Unchecked="HandleUnchecked" Indeterminate="HandleThirdState" />
4、 DataGrid、ListBox、ListView、TreeView,都是用來以行列形式顯示的控件,前三個(gè)都是幾行幾列的形式,而最后一個(gè)TreeView則是顯示出來一種樹形結(jié)構(gòu)。
以上幾種控件可以用來進(jìn)行數(shù)據(jù)綁定xml數(shù)據(jù)或者是數(shù)據(jù)庫(kù),每一種都有不同的形式?;镜娘@示圖如下所示:
TreeView:
而TextBox也可以用來做數(shù)據(jù)綁定,可以關(guān)聯(lián)其他的控件對(duì)象,來實(shí)現(xiàn)想要顯現(xiàn)的效果。
核心用戶輸入控件,除了上面列出來的這些之外,還有許多,例如:Calendar、Slider、TabControl等等,它們一起構(gòu)成了WPF的完整的輸入控件族,是用戶創(chuàng)建界面的核心。
二、 窗口修飾控件
1、 Menu控件,菜單控件,相信大家都不陌生,先看下面的xaml:
<Grid> <Menu> <MenuItem Header="First" > <MenuItem Header="second"/> <MenuItem Header="secend"> <MenuItem Header="third" Click="Handler"/> </MenuItem> </MenuItem> </Menu> </Grid>
顯示的界面:
由此可以看出,菜單控件是利用MenuItem子項(xiàng)形成層級(jí)結(jié)構(gòu),并且可以為每一個(gè)菜單項(xiàng)設(shè)置Click事件。上面實(shí)例沒有設(shè)置菜單的高度,故而菜單鋪滿全局。
菜單項(xiàng)有幾個(gè)屬性需要注意一下上圖中可以看出,一個(gè)子菜單主要有三個(gè)部分,其中一個(gè)是顯示內(nèi)容,內(nèi)容前面有個(gè)空白(這是一個(gè)圖標(biāo)Icon的占位空白),還有子項(xiàng)后面的那個(gè)黑色的三角箭頭。
Icon:可以設(shè)置菜單的圖標(biāo),其內(nèi)容可以是一個(gè)image空間,用法如下:
<MenuItem.Icon> <Image Source="Delete.png"/> </MenuItem.Icon>
其中source指向你想要顯示為Icon的圖片。
Header:菜單的內(nèi)容,設(shè)置如上的xaml所示。
2、 ToolBar控件,工具條菜單。ToolBar 是一個(gè) HeaderedItemsControl 。其內(nèi)容屬性為 Items 和 ItemsSource ,其標(biāo)頭屬性為 Header 。基本用法看下面xaml:
<ToolBarTray Background="White"> <ToolBar Band="10" BandIndex="10"> <Button> <Image Source="Ore.jpg" /> </Button> <Separator/> <Button> <Image Source="Ore.jpg" /> </Button> </ToolBar> </ToolBarTray>
其中Separator表示分隔條,可以為工具條中的每個(gè)按鈕設(shè)計(jì)單擊事件打開某一程序。
工具條默認(rèn)顯示為橫向,如果想要縱向顯示需要設(shè)置工具條的Orientation屬性。
工具條大概顯示如下:
4、 ToolTip控件, Tooltip控件是一個(gè)簡(jiǎn)單,但非常有用的控件。它能夠?yàn)槲覀兊能浖峁┓浅F恋奶崾拘畔?,提高軟件的可用性,給用戶比較好的體驗(yàn)。上xaml:
<Button Height="25" Content="提示工具演示" HorizontalAlignment="Center"> <Button.ToolTip> <ToolTip Background="#60AA4030" Foreground="White" HasDropShadow="False" Placement="Mouse"> <StackPanel> <TextBlock Margin="3">提示語(yǔ):這是什么?</TextBlock> <!--<Image Source="black.jpg" Stretch="Fill"/>--> <TextBlock Margin="3">傳說中的3億網(wǎng)站。</TextBlock> </StackPanel> </ToolTip> </Button.ToolTip> </Button>
5、 ProgressBar控件,進(jìn)度條。進(jìn)度條有兩個(gè)屬性Minimum和Maximum,可以用這兩個(gè)屬性綁定事件來實(shí)現(xiàn)進(jìn)度條的進(jìn)展操作。一般情況下,進(jìn)度條用于啟動(dòng)時(shí)間過長(zhǎng)需要等待而給用戶帶來的一個(gè)視覺加載效果。
其中有個(gè)IsIndeterminate屬性設(shè)置進(jìn)度條的進(jìn)度動(dòng)畫,設(shè)為TRUE的時(shí)候,會(huì)顯示進(jìn)度信息。默認(rèn)情況是FALSE。
三、 媒體控件
2、 MediaElement控件,在WPF 中可以使用MediaElement 為應(yīng)用程序添加媒體播放控件,以完成播放音頻、視頻功能。由于MediaElement 屬于UIElement,所以它同時(shí)也支持鼠標(biāo)及鍵盤的操作。
3、 SoundPlayerAction控件, WPF定義了一個(gè)SoundPlayerAction類(繼承自TriggerAction),它用一種友好的方式封裝了SoundPlayer類。這樣做的好處是,可以在控件的EventTrigger中添加SoundPlayerAciton動(dòng)作,進(jìn)而可以播放音頻文件。
例如:
<Button Content="xirihanlin"> <Button.Triggers> <EventTrigger RoutedEvent="Button.Click"> <SoundPlayerAction Source="BLOW.WAV"/> </EventTrigger> </Button.Triggers> </Button>
有SoundPlayerAction類的一個(gè)好處是你不用為播放音頻文件而在后臺(tái)書寫代碼。但是,這樣的好處也會(huì)給你帶來限制,因?yàn)槟愀緹o(wú)法控制SoundPlayerAction與SoundPlayer之間的交互。
當(dāng)點(diǎn)擊Button時(shí),會(huì)創(chuàng)建SoundPlayerAction對(duì)象,而SoundPlayerAction內(nèi)部構(gòu)建了一個(gè)SoundPlayer實(shí)例,并把SoundPlayerAction的Source屬性值傳給了SoundPlayer實(shí)例,并調(diào)用了SoundPlayer的Play,而事實(shí)上,由于音頻文件沒有提前加載,你將不能在點(diǎn)擊的同時(shí)就能聽見聲音。因此,使用SoundPlayerAction類的限制還包括無(wú)法提前加載文件和設(shè)置循環(huán)播放等。
相關(guān)文章
C# Windows API應(yīng)用之基于FlashWindowEx實(shí)現(xiàn)窗口閃爍的方法
這篇文章主要介紹了C# Windows API應(yīng)用之基于FlashWindowEx實(shí)現(xiàn)窗口閃爍的方法,結(jié)合實(shí)例形式分析了Windows API函數(shù)FlashWindowEx的功能、定義及實(shí)現(xiàn)窗口閃爍的相關(guān)技巧,需要的朋友可以參考下2016-08-08C#實(shí)現(xiàn)對(duì)象的序列化和反序列化
這篇文章介紹了C#實(shí)現(xiàn)對(duì)象序列化和反序列化的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07C#中單問號(hào)(?)和雙問號(hào)(??)的用法整理
本文詳細(xì)講解了C#中單問號(hào)(?)和雙問號(hào)(??)的用法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05C#定時(shí)器實(shí)現(xiàn)自動(dòng)執(zhí)行的方法
這篇文章主要介紹了C#定時(shí)器實(shí)現(xiàn)自動(dòng)執(zhí)行的方法,實(shí)例分析了C#定時(shí)器參數(shù)的設(shè)置及方法的調(diào)用與實(shí)現(xiàn),需要的朋友可以參考下2015-01-01c# 實(shí)現(xiàn)康威生命游戲(細(xì)胞自動(dòng)機(jī))的示例
這篇文章主要介紹了c# 實(shí)現(xiàn)康威生命游戲(細(xì)胞自動(dòng)機(jī))的示例,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下2021-02-02一種c#深拷貝方式完勝java深拷貝(實(shí)現(xiàn)上的對(duì)比分析)
下面小編就為大家?guī)硪黄环Nc#深拷貝方式完勝java深拷貝(實(shí)現(xiàn)上的對(duì)比分析)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-07-07