生活随笔
收集整理的這篇文章主要介紹了
X--名称空间详解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
轉自:http://blog.csdn.net/lisenyang/article/details/18312039
X名稱空間里面的成員(如X:Name,X:Class)都是寫給XAML編譯器看的、用來引導XAML代碼將XAML代碼編譯為CLR代碼。
4.1X名稱空間里面到底都有些什么?
x名稱空間映射的是:http://schemas.microsoft.com/winfx/2006/xaml,望文生義,它包含的類均與解析XAML語言相關,所以亦稱之為“XAML名稱空間”。
與C#語言一樣,XAML也有自己的編譯器。XAML語言被解析并編譯,最終形成微軟中間語言保存在程序集中。在解析和編譯XAML的過程中,我們經常要告訴編譯器一些重要的信息,如XAML編譯的結果應該和哪個C#代碼編譯的結果合并、使用XAML聲明的元素是public還是private訪問級別等等。這些讓程序員能夠與XAML編譯器溝通的工具就存在X:名稱空間中。
我們注意到,它分為Attribute、標簽擴展、XAML指令元素三個種類。下面我們講講它們的具體用法:
4.2 ? ? ?X名稱空間中的Attribute
前面我們已經講過,Attribute和Property是兩個層面上的東西,Attribute是語言層面上的東西,是給編譯器看的,Property是面向對象層面上的東西,是給編程邏輯看。而且一個標簽中的Attribute大部分對應對象的Property。在使用XAML編程的時候,如果你想給它加一點特殊的標記來改變XAML對它的解析,這時候就需要額外的給它添加一些Attribute了。比如,你想告訴XAML編譯器將哪個編譯結果和那個C#編譯的類合并,這時候就必須為這個標簽添加X:Class ?Attribute來告訴編譯器。X:Class并不是對象成員,而是重X空間硬貼上去的。讓我們瀏覽一下常用的Attribute。
4.2.1 ? ?x:Class
這個Attribute是告訴XAML編譯器將XAML編譯器編譯的結果和后臺編譯結果的哪一個類進行合并,使用x:Class有以下幾點要求:
?
- 這個Attribute只能用于根節點。
- 使用x:Class的根節點的類型要與x:Class的值所指示的一致。
- x:Class的值所指示的類型在聲明的時候必須使用partial關鍵字。
- x:Class已經在剖析最簡單的XAML的時候已經講過,在這就不多講了。
?
4.2.2 ? ? X:ClassModiffier
這段代碼是告訴XAML編譯器有標簽編譯成的類具有什么樣的訪問級別。
使用這個Attribute的時候需要注意的是:
?
- 標簽必須具有x:Class Attribute。
- X:ClassModiffier的值必須與X:Class所指定類的訪問權限一致。
- X:ClassModiffier的值隨后臺代碼編譯語言的不同而有所不同。
4.2.3 ? ?X:Name 我們之前已經提過XAML是一種聲明式語言,但你是否想過XAML標簽聲明的是什么呢?其實,XAML標簽聲明的是對象,一個XAML對應著一個對象,這個對象一般是一個控件類的實例。在.NET平臺上,類是引用類型。引用類型的實例一般都是以“引用者---實例”的形式成對出現的,而且我們只能通過引用者來訪問實例。當一個實例不在被任何引用者引用的時候,它將作為內存垃圾被銷毀。 常見的引用者是引用變量,但不是唯一的。比如下面這段XAML代碼:
[html]?view plaincopyprint?
<Window?x:Class="WpfApplication2.Window5"??????????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"?? ????????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"?? ????????Title="Window5"?Height="300"?Width="300">?? ????<Grid>?? ????????<StackPanel?Height="218"?HorizontalAlignment="Left"?Margin="19,31,0,0"??VerticalAlignment="Top"?Width="237">?? ????????????<TextBox?Height="23"?Width="120"?/>?? ????????????<Button?Content="Button"?Height="23"?Width="75"?/>?? ????????</StackPanel>?? ????</Grid>?? </Window>?? 這篇代碼中通篇沒有出現一次名字,但是我們可以通過引用者的層級關系來找到我們最終想要的控件,我們在Button的Click下寫如下代碼:
[csharp]?view plaincopyprint?
private?void?Button_Click(object?sender,?RoutedEventArgs?e)?????????{?????????????StackPanel?panel?=?this.Content?as?StackPanel;?? ???????????TextBox?textBox?=?panel.Children[0]?as?TextBox;?? ???????????if?(!string.IsNullOrEmpty(textBox.Name))?? ???????????{?????????????????textBox.Text?=?textBox.Text;?????????????}?????????????else?? ???????????{?????????????????textBox.Text?=?"NULL";?? ???????????}?????????}?? this.Content引用著StackPanel的實例,StackPanel.Children[0]又引用著TextBox的實例。知道了這個關系,就可以一路順著查找下來并同時進行類型轉換,最終TextBox中顯示的值是NULL。 理論上我們可以用上面的方法訪問到UI上的所有元素,但這畢竟太麻煩了。換句話說:XAML這種對象聲明語言只負責聲明對象而不負責為這些對象聲明引用變量。如果我們需要為對象準備一個引用變量以便在C#中直接訪問就必須顯示的告訴XAML編譯器-----為這個對象聲明引用變量,這時候,X:Name就派上用場了。 注意: X:Name的作用有兩個: (1)告訴編譯器,當一個標簽帶有x:Name時,除了為這個標 這個還真不能確定!簽生成實例還要給這個標簽聲明一個引用變量,變量名就是x:Name的值。 (2)將XAML標簽所對應的Name屬性(如果有)也設置為x:Name值,并把這個值注冊到UI樹上,以方便查找。 4.2.4 ? ? x:FieldModifier 使用了x:Name后,XAML標簽對應的實例就具有了自己的引用變量,而且這些引用變量都是類的字段,既然這樣就不免要關注一下它的訪問級別。默認情況下這些字段的級別都被設置成了Internal。在編程的時候,有的時候需要用一個程序集里的一個窗體元素訪問到另一個程序集的窗體元素,那么就需要使用x:FieldModifier來改變變量的訪問級別!
[html]?view plaincopyprint?
<StackPanel?Height="218"?HorizontalAlignment="Left"?Margin="19,31,0,0"??VerticalAlignment="Top"?Width="237">??????????????<TextBox?Height="23"?Width="120"?x:Name="txtName"?x:FieldModifier="internal"/>?? ????????????<Button?Content="Button"?Height="23"?Width="75"?Click="Button_Click"?x:Name="btntest"?x:FieldModifier="public"/>?? ????????</StackPanel>?? 因為x:FidleModifier是應用變量的訪問級別,所以要配合x:Name一起使用。否則沒有引用變量,何來引用變量訪問級別。 4.2.5 ? ?x:Key 最自然的檢索方式莫過于”key-value“的形式了。在XAML文件中,我們可以把需要多次使用的類容提取出來放在資源字典中,需要使用的時候就用這個資源的key將這個資源檢索出來。 x:key的作用就是使用為資源貼上用于檢索的索引。在WPF中,幾乎每個元素都有自己的Resource屬性,這個屬性就是“key-value”的集合。只要把元素放進這個集合里,這個元素就成了資源字典中的一個條目。當然,為了能檢索到這個條件,就必須為它添加x:Key。資源在WPF中非常重要,需要重復使用的XAML內容,如Style,各種Template和動畫都需要放在資源里。 先讓我們看XAML代碼:
[html]?view plaincopyprint?
<Window?x:Class="WpfApplication2.Window4"??????????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"?? ????????xmlns:local="clr-namespace:WpfApplication2"?? ????????Title="Window4"?Height="369"?Width="675">?? ????<Window.Resources>?? ????????<local:Human?x:Key="human"?Child="ABC"></local:Human>?? ????????<sys:String?x:Key="myString">測試</sys:String>?? ????????<Style?x:Key="{x:Type?Button}"?TargetType="{x:Type?Button}">?? ????????????<Setter?Property="Width"?Value="30"></Setter>?? ????????????<Setter?Property="Background"?Value="black"></Setter>?? ????????</Style>?? ????</Window.Resources>?? ????<Grid>?? ??????????????????<Label?Content="{?StaticResource?ResourceKey=myString}"?Height="28"?HorizontalAlignment="Left"?Margin="177,81,0,0"?Name="label1"?VerticalAlignment="Top"?/>?? ????</Grid>?? </Window>?? 資源不但可以在XAML中使用,也可以在C#中訪問,C#中使用如下方式:
[csharp]?view plaincopyprint?
string?str?=?this.FindResource("myString")?as?string;??this.label1.Content?=?str;?? 4.2.6 ? ?x:Shared 學習x:key的時候我們已經了解到,如果把某個對象作為資源放入資源字典里后我們就可以把它們檢索起來重復使用。那么每當我們檢索到一個對象,我們得到的究竟是同一個對象呢,還是這個對像的一個副本呢?這就要看我們為x:Shared賦什么值了。x:Shared一定要與x:Key配合使用,如果x:Shared值為true,那么每次檢索這個對象的時候,我們得到的都是同一個對象,反之,我們得到的就是這個對象的一個副本。默認這個值是true。也就是說我們使用的都是同一個對象。 4.3 ? ? ? x名稱空間下的擴展標簽 標記擴展實際就是一些MarkupExtension類的直接或間接派生類。x名稱空間中就包含一些這樣的類,所以稱其為x名稱空間標簽的標記擴展。 4.3.1 ? x:Type 顧名思義,x:Type應該是一個數據類型的名稱。一般情況下,我們在編程中操作的數據類型實例或者實例的引用。但有的時候我們也需要用到數據類型本身。 能讓程序員在編程的層面上自由的操作這些數據類型,比如在不知道具體類型的情況下創建這個類型的實例并嘗試調用它的方法,.NET命名空間里還包含了名為Type的類做為所有數據類型在編程層面上的抽象。 當我們想在XAML中表達某一數據類型就需要用到x:Type標記擴展。比如某個類的一個屬性,它的值要求的是一個數據類型,當我們在XAML中為這個屬性賦值是就需要用到x:Type。請看下面這個例子:
[html]?view plaincopyprint?
<UserControl?x:Class="WpfApplication2.UserControl1"???????????????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"?? ?????????????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"?? ?????????????xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"??? ?????????????xmlns:d="http://schemas.microsoft.com/expression/blend/2008"??? ?????????????mc:Ignorable="d"??? ?????????????d:DesignHeight="52"?d:DesignWidth="128">?? ????<Grid>?? ????????<Button?Content="Button"?Height="30"?HorizontalAlignment="Left"?Margin="10,10,0,0"?Name="button1"?VerticalAlignment="Top"?Width="106"?Click="button1_Click"?/>?? ????</Grid>?? </UserControl>?? [csharp]?view plaincopyprint?
??? ??? ???public?partial?class?UserControl1?:?UserControl?? ???{?????????public?UserControl1()?? ???????{?????????????InitializeComponent();?????????}?????????public?Type?MyWindowType?{?get;?set;?}?? ???????private?void?button1_Click(object?sender,?RoutedEventArgs?e)?? ???????{?????????????Window?myWin?=?Activator.CreateInstance(this.MyWindowType)?as?Window;?? ???????????if(myWin!=null)?? ???????????{?????????????????myWin.Show();?????????????}?????????}?????}?? [html]?view plaincopyprint?
<Window?x:Class="WpfApplication2.Window4"??????????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"?? ????????xmlns:local="clr-namespace:WpfApplication2"?? ????????Title="Window4"?Height="369"?Width="675">?? ????<Window.Resources>?? ????????<local:Human?x:Key="human"?Child="ABC"></local:Human>?? ????????<sys:String?x:Key="myString">測試</sys:String>?? ????????<Style?x:Key="{x:Type?Button}"?TargetType="{x:Type?Button}">?? ????????????<Setter?Property="Width"?Value="30"></Setter>?? ????????????<Setter?Property="Background"?Value="black"></Setter>?? ????????</Style>?? ????</Window.Resources>?? ????<Grid>?? ??????????????????<local:UserControl1?HorizontalAlignment="Left"?Margin="292,244,0,0"?x:Name="userControl11"?VerticalAlignment="Top"?MyWindowType="{x:Type?TypeName=local:Window1}"/>?? ????</Grid>?? </Window>?? 回顧一下之前的標記擴展語法,因為TypeExtension類的構造器可以接受數據類型名做為參數,所以我們完全可以這樣寫:
[html]?view plaincopyprint?
UserWindowType="{x:Type?local:Window1}"?? 編譯并運行程序,單擊主窗體上的按鈕,自定義窗口就會顯示出來,我們還可以多寫幾個窗體來擴展這個程序,到時后只需要修改MyWindowType里面的值就可以了。 4.3.2 ? ? ? x:Null 在XAML里面表示空值就是x:Null。 大部分時間我們不需要為屬性附一個Null值,但如果一個屬性就有默認值而我們有不需要這個默認值就需要用的null值了。在WPF中,Style是按照一個特定的審美規格設置控件的各個屬性,程序員可以為控件逐個設置style,也可以指定一個style目標控件類型,一旦指定了目標類型,所有的這類控件都將使用這個style----除非你顯示的將某個實例的Style設置為null。 請看下面的事例:
[html]?view plaincopyprint?
<Window?x:Class="WpfApplication2.Window4"??????????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"?? ????????xmlns:local="clr-namespace:WpfApplication2"?? ????????Title="Window4"?Height="369"?Width="675">?? ????<Window.Resources>?? ?????????????????<Style?x:Key="{x:Type?Button}"?TargetType="{x:Type?Button}">?? ????????????<Setter?Property="Width"?Value="30"></Setter>?? ????????????<Setter?Property="Background"?Value="black"></Setter>?? ????????</Style>?? ????</Window.Resources>?? ????<Grid>?? ????????????????<Button?Content="Button"?Height="23"?HorizontalAlignment="Left"?Margin="180,256,0,0"?Name="button1"?VerticalAlignment="Top"?Click="button1_Click"?/>?? ????????<Label?Content="{?StaticResource?ResourceKey=myString}"?Height="28"?HorizontalAlignment="Left"?Margin="177,81,0,0"?Name="label1"?VerticalAlignment="Top"?/>?? ?????????????????<Button?Content="Button"?Height="23"?HorizontalAlignment="Left"?Margin="10,10,0,0"?Name="button2"?VerticalAlignment="Top"?/>?? ????????<Button?Content="{x:Static?local:Window4.Test}"?Height="23"?HorizontalAlignment="Left"?Margin="128,12,0,0"?Name="button3"?VerticalAlignment="Top"?Style="{x:Null}"/>?? ?????????????</Grid>?? </Window>?? 當然了,x:null也可以使用屬性標簽來設置這個值,前面已經講過,在這就不在講了。 4.3.3 ? ? ? x:Array 通過它的item屬性向使用者暴露一個類型已知的ArrayList實例,ArrayList內成員的類型由x:Array的Type指明。下面這個例子就是把ArrayList做為數據源向一個ListBox提供數據:
[html]?view plaincopyprint?
<Window?x:Class="WpfApplication2.Window4"??????????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"?? ????????xmlns:local="clr-namespace:WpfApplication2"?? ????????Title="Window4"?Height="369"?Width="675">?? ??????????<Grid>?? ????????????????????????????????????<ListBox?Height="100"?HorizontalAlignment="Left"?Margin="435,110,0,0"?Name="listBox1"?VerticalAlignment="Top"?Width="176">?? ????????????<ListBox.ItemsSource>?? ????????????????<x:Array?Type="sys:String">?? ????????????????????<sys:String>Jim</sys:String>?? ????????????????????<sys:String>Darren</sys:String>?? ????????????????????<sys:String>Frank</sys:String>?? ????????????????</x:Array>?? ????????????</ListBox.ItemsSource>?? ????????</ListBox>?? ????</Grid>?? </Window>?? 4.3.4 ? ? ? ?x:Static 這是一個很常用的標記擴展,它的作用是在XAML文檔中使用數據類型為static的成員。因為XAML不能編寫邏輯代碼。所以使用x:Static訪問的static成員一定是數據類型的屬性和字段。我們看如下一些例子:
[csharp]?view plaincopyprint?
public?Window4()?????????{?????????????InitializeComponent();????????????? ??????????? ??????????? ???????}???????????public?static?string?Test?=?"明月松間照,清泉石上流。";?? [html]?view plaincopyprint?
<Window?x:Class="WpfApplication2.Window4"??????????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"?? ????????xmlns:local="clr-namespace:WpfApplication2"?? ????????Title="Window4"?Height="369"?Width="675">?? ???<Grid>?? ????????<Button?Content="{x:Static?local:Window4.Test}"?Height="23"?HorizontalAlignment="Left"?Margin="128,12,0,0"?Name="button3"?VerticalAlignment="Top"?Style="{x:Null}"/>?? ????????????</Grid>?? </Window>?? 如果一個程序需要支持國際化,一般需要把顯示的字符串保存在一個資源類的Static屬性中,所以支持國際化的程序UI中對x:Static的使用相當的頻繁。 4.4 ? ? ? ?XAML指令元素
XAML指令元素只有兩個:
我們之前已經在代碼后置一節介紹過x:Code標簽,它的作用是可以在XAML文檔中可以編寫后置的C#后臺邏輯代碼,這樣做的好處就是不需要把XAML和C#分放在兩個文檔當中,這樣寫的問題是代碼不容易維護,不宜調試,一般沒有人愿意這么干。 x:XData是一個專用標簽。WPF把包含數據的對象稱為數據源,用于把數據源中的數據提供給數據使用者的對象被稱做是數據提供者,WPF中包含多種數據提供者,其中一個類名叫做XmlDataProvider實例,那么XmlDataProvider實例的數據就要放在x:XData的標簽內容里。事例如下:
小結: 我已經比較完整的掌握了XAML的語法和常用元素。
總結
以上是生活随笔為你收集整理的X--名称空间详解的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。