WPF 雜談——資源文件


編寫一個應用難免要用到WPF本身的控件。不管是WinForm還是網頁都會有自己的控件。只是在寫法和用法上有所不同而以。而控件命名卻離不開那幾個單詞。所以不用擔心判斷不出來哪個是按扭,哪個是文本框。舉個例子吧。

HTML

 <input type="button" value="扭按" />

WinForm

 private System.Windows.Forms.Button button1;

WPF

  <Button  Content="按扭"/>

看到了吧。本質上來講沒有什么區別。只要學習他的屬性用法就可以了。

在設計業務界面的時候,我們一定離不開對界面進行相應的布局。網頁上常常會用到DIV+CSS來進行布局。只是筆者想要講的不是要用到什么技術。而是用到的知識。如:HTML里面用於布局元素有DIV、SPAN、Table等。又好比如:WinForm里面常常會用Panel。那么WPF里面是不是也有類似這樣子的知識點。這是當然了。值得注意的是PC端(C/S)和網頁(B/S)在布局上有所不同。PC端這邊多出了一個布局方式的知識點。一般有分為絕對布局(AbsoluteLayout),邊框布局(BorderLayout),流布局(FlowLayout),表格布局(TableLayout),錨點布局(AnchorLayout)等。但是不是什么布局都存在。這個要看設計這門技術的人有沒有把所有的布局都包進來。

WPF用於布局的元素有:Grid,StackPanel,WrapPanel。這些全是布局方式的知識。如下

Grid:表格布局或是絕對布局。

StackPanel:線性布局(要么垂直要么水平)。

WrapPanel:流布局。

可以說上面這三個元素足夠讓你們布局出令流目的界面出來。但是這只是用於界面上的划分。而想要做的美麗和漂亮就要用到樣式(Style)。

筆者學習WPF的樣式,最開始是以CSS樣式來學習。如:CSS有三種方式來實現——外部樣式,內部樣式,內嵌樣式。WPF的樣式(Style)實現有幾種方式呢?筆者從開發過程得出來——二種。沒有了內嵌樣式。但是卻又多出了一種概念。這個概念跟控件有關系。所以筆者就在網頁上面下載了一個圖片。如下

我們可以從圖片上看到所有常用到的控件都會繼承於FrameworkElement類。在FrameworkElement類里面有一個屬性叫Resources。這個屬性里面可以創建和存放各種各樣的樣式。這就意味着每一個控件都有自己的樣式存放的地方。也就是說樣式的作用可以控制到某個控件的范圍。雖然網頁也可以隨時隨地的創建CSS樣式。只要在聲明的Style里面就行了。但是他還是作用於整個網頁。所以WPF在控件或是Window窗體里面聲明的樣式筆者都喜歡叫他們為內部樣式。

網頁上的外部樣式是引用一個外部文件。而這個外部文件里面存放大量的CSS樣式。同樣子WPF也是這樣子的。但是有一個區別的——范圍。網頁上的外部文件最終作用只能是某個網頁,但是WPF的作用可以是整個應用。不管是多少個Window,多少個UserControl。就是上一章中講到的在Application里面設置引用的外部文件。也是筆者認為的外部樣式。如下

 <ResourceDictionary Source="/FirstFloor.ModernUI;component/Assets/ModernUI.xaml" />

 即然每一個控件都會有自己的樣式資源,那問題來了——如果倆個樣式對同一個對象進行修飾,那么他要什么樣子選擇呢?舉一個小小的例子吧。

<Window x:Class="WpfApp.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">
    <Window.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="Foreground" Value="Red"></Setter>
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.Resources>
            <Style TargetType="TextBlock">
                <Setter Property="Foreground" Value="Blue"></Setter>
            </Style>
        </Grid.Resources>
        <TextBlock Text="1223"></TextBlock>
    </Grid>
</Window>

運行結果:

筆者在Window窗體里面寫了一個對TextBlock控件進行修飾的樣式,同時前景色設為紅色。在Grid也寫了一個對TextBlock控件進行修飾的樣式,只是這個顏色為藍色。結果我們可以看到他會選擇最近的樣式。

上面列子里面筆者是對所有的TextBlock控件進行修飾。跟CSS樣式里面的元素選擇器有一點類似。往往一般用於自定義控件。還有一種寫法,跟CSS樣式里面的類選擇器有一點類似。如下

 1     <Style x:Key="AlertButton" TargetType="ButtonBase" BasedOn="{StaticResource SystemButtonBase}">
 2         <Setter Property="Cursor" Value="Hand" />
 3         <Setter Property="Margin" Value="8"/>
 4         <Setter Property="Padding" Value="4"/>
 5         <Style.Triggers>
 6             <Trigger Property="IsMouseOver" Value="True">
 7                 <Setter Property="Opacity" Value=".7" />
 8             </Trigger>
 9             <Trigger Property="IsPressed" Value="True">
10                 <Setter Property="Opacity" Value=".4" />
11             </Trigger>
12         </Style.Triggers>
13     </Style>

上面的代碼來自於開源項目FirstFloor.ModernUI里面的。“x:Key”就是相當於CSS樣式里面的"."。除了這些之外我們還是可以看到baseOn,它用於繼承的。相信大家都可以看得懂是什么意思。Setter用於設置當前的屬性值。Style.Triggers用於一些觸發動作設置。比如按扭按下時要發生一些什么樣子的變化。Property="IsPressed" Value="True"就是相當於IF。當前按扭按下去時候,IsPressed的值會變成True。發現服合當前的一個觸發條件。於是就開始執行相應的設置工作。如:上面透明度(Opacity)會成.4。

當前除了上面講到的樣式之外,資源還可以存放別的東西。如:顏色。算了。只有文字的說明不能夠明顯和直接。在筆者在舉個列子吧。

 1 <Window x:Class="WpfApp.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:sys="clr-namespace:System;assembly=mscorlib"
 5         Title="MainWindow" Height="350" Width="525">
 6     <Window.Resources>
 7         <sys:String x:Key="TestString">I am Aomi</sys:String>
 8     </Window.Resources>
 9     <Grid>
10         <TextBlock Text="{StaticResource TestString}"></TextBlock>
11     </Grid>
12 </Window>

運行結果:

我們可以看到。資源文件不只是樣式,還可以存放一些系統的值。但是一定要注意引用。如上面的xmlns:sys="clr-namespace:System;assembly=mscorlib"。

在引用樣式方面,WPF也分為靜態和動態的差別。如上面是靜態引用。動態則要用到關鍵字DynamicResource。那么動態資源和靜態資源的概念就出來。記得以前有人問過筆者他們之間到底有什么差別。筆者連什么是動態資源,什么是靜態資源都搞不清楚。

靜態資源(StaticResource):會在加載xaml文件的時候進行初始化,而且只有一次。同時運行的時候是不能對資源進行相關的操作。這就意味着后面如果對資源進行修改,是不會同步相應的引用。

動態資源(DynamicResource):會在運行的時候進行初始化,同時運行的時候也可以操作。顯然后面對資源進行修改會同步到相應的引用。

知道這些之后,讓筆者做了例子吧。就按上面的列子稍微的修改一下吧。

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <sys:String x:Key="TestString">I am Aomi</sys:String>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition Height="auto" />
        </Grid.RowDefinitions>
        <TextBlock x:Name="TbText" Grid.Row="0" Text="{DynamicResource TestString}"></TextBlock>
        <Button Grid.Row="1" Content="變化" Click="Button_Click"></Button>
    </Grid>
</Window>

后台按扭的代碼:

 private void Button_Click(object sender, RoutedEventArgs e)
        {
            this.Resources["TestString"] ="aaa";
        }

動態資源的執行結果:

把上面的引用改成如下靜態引用。

 <TextBlock x:Name="TbText" Grid.Row="0" Text="{StaticResource TestString}"></TextBlock>

靜態資源的執行結果:

至於到底是用動態資源好,還是用靜態資源好呢?筆者是這樣子理解的:靜態資源他只會在編譯的時候加載一次。后面哪怕你修改他資源也不會發生變化。而動態資源會在編譯的時候也初始化,只是這個時候的值並沒有被初始化。只有在運行過程中需要的時候才會去加載值。所以呢?如果在項目過程中不需要后面修改變化的話,可以試着用靜態資源。要明白動態資源可不是加載一次哦。性能還是要想一想的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM