天天看點

WPF之XAML,命名空間 元素嵌套 屬性聲明 字元與對象的轉換什麼是XAMLXAML的文法

WPF之XAML

  • 什麼是XAML
  • XAML的文法
    • XAML的命名空間
    • XAML元素的嵌套與屬性的申明
    • XAML的字元與對象的轉換機制

什麼是XAML

下面的段落來自于WPF程式設計寶典

XAML(Extensible Application Markup Language 的簡寫,發音為“zammel”)是用于執行個體

化.NET對象的标記語言。盡管XAML是一種可以應用于不同問題領域的技術,但主要用于構

造WPF使用者界面。換句話說,XAML文檔定義了在WPF應用程式中組成視窗的面闆、按鈕以

及各種控件的布局。

不再手動編寫XAML,您将使用工具生成所需的XAML。如果您是一“位圖形設計人員,該

工具可能是圖形設計程式,如Expression Blend。 如果您是一位開發人員,您開始時可能使用:

Visual Studio。 因為這兩個工具在生成XAML時本質上是相同的,是以可以使用Visual Studio

建立一個基本使用者界面,然後将該界面移交給-一個出色的設計團隊,而設計團隊在Expression

Blend中使用自定義圖形潤色這一-界面。實際上,将開發人員和設計人員的工作流程內建起來

的能力,是Microsoft推出XAML的主要原因之一。

xaml的優勢其實不止這些,在圖形設計方面,我們可以快捷的通過編寫xaml來辨別生成的對象。比如要生成一個button就是

<Button />

。如果我們要在button裡面放置不同的内容時,比如放置一串文本,就可以這樣寫 :

<Button Content="sdf" />
           

亦或者

<Button>sdf</Button>
           

還可以

<Button>
        <TextBlock Text="sdf"/>
    </Button>
           

但是這樣子的自由性,同樣也造成了一個問題。就是xaml對于初學者的可讀性的非常差。以前我剛接觸wpf的xaml時候,就對這些不用語句相同結果一臉懵逼。網上看别人寫的xaml代碼的時候同樣也是不知道他們在寫什麼。

是以要編寫WPF程式, xaml肯定是學好的。

XAML的文法

XAML的命名空間

在建立一個頁面的時候,編輯器會給我添加上預設的幾個空間,如下圖:
           
WPF之XAML,命名空間 元素嵌套 屬性聲明 字元與對象的轉換什麼是XAMLXAML的文法

這些都是預設導入的空間,你能夠在xaml編輯的時候直接點出來的對象都是在這些空間中的。

文法規則 xmlns:空間名=“路徑”。這個路徑可以是url,可以是其他的格式,例如上圖中的 clr-namespace:WpfApp2。他這裡就吧WpfApp2這個namespace定義成了local。之後我們就可以用**local:類名**來生成對象。例如之前做的一個datacontext(類名是text,namespace為 WpfApp2 ):

類的代碼如下

namespace WpfApp2
{
    	public  class test
        {
            public test() {
                Name = "222";
                Say = new Say();
                     
            }
            public string Name { get; set; }
            public Say Say { get; set; }
        }
}
           
WPF之XAML,命名空間 元素嵌套 屬性聲明 字元與對象的轉換什麼是XAMLXAML的文法

在這裡申明是代表在這個父節點中引入這個空間。這樣他的所有子節點,就都可以使用這些空間裡面的類。如果隻想在單獨的一個節點中申明的話可以這樣子寫。

<Window x:Class="WpfApp2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"

        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <!--xmlns:local="clr-namespace:WpfApp2"-->
    <Window.DataContext>
        <local:test xmlns:local="clr-namespace:WpfApp2"/>     <!--這裡是重點-->
    </Window.DataContext>
           
WPF之XAML,命名空間 元素嵌套 屬性聲明 字元與對象的轉換什麼是XAMLXAML的文法

XAML元素的嵌套與屬性的申明

上文中我們舉例了一個button的申明方式。

最簡單的就像這樣子

<Button Content="sdf" />
           

他首先建立了一個button的對象,然後再申明了他的Content屬性,值為sdf。當然申明他的屬性還可以這樣子,

<Button>
        <Button.Content>
            sdf
        </Button.Content>
    </Button>
           

這裡就要說明一下了。申明屬性的時候,可以再他節點的後面跟着寫上,也可以在他的第一級子節點上按照<标簽名字.他裡面的屬性>來申明。Button就是标簽名字,Content就是他的屬性。

當然,因為content是在ContentControl裡面的,而且大部分控件都是繼承于ContentControl。是以微軟額外搞了一個省略的寫法。如下:此寫法就相當于在給Button.Content指派sdf。

<Button> 
	 sdf
</Button>
           

當然,并不是所有的控件都是繼承ContentControl的。就例如StackPanel,所有的容器都繼承于Panel。它裡面的預設屬性是Children而不是ContentControl的Button(像什麼listview之類的他們是繼承于ItemsControl,他們是把控件集合items放入到panel中的。listview的預設panel就是VirtualizingStackPanel,這些日後再聊)。

panel裡面的Children不能被快捷的申明,但是ItemsControl的items是可以的。如下

<ListView>
    sdf
    sdf
    sdf
    sdf
</ListView>
           
WPF之XAML,命名空間 元素嵌套 屬性聲明 字元與對象的轉換什麼是XAMLXAML的文法

當然啦,其實這是一個假象,因為他生成的并不是4個item。而是一個item中包含了4個sdf以及3個空格。

他省略的是listviewitem的對象的申明。

我們修改下代碼

<ListBox>
            <TextBlock   Text="sdf"/>
            <TextBlock   Text="sdf"/>
            <ListViewItem>
                <TextBlock   Text="sdf"/>
            </ListViewItem>
            <ListViewItem>
                sdf
            </ListViewItem>
        </ListBox>
           

效果如下:

WPF之XAML,命名空間 元素嵌套 屬性聲明 字元與對象的轉換什麼是XAMLXAML的文法

看吧,效果是一樣的

XAML的字元與對象的轉換機制

我們在xaml上申明的都是字元,然後為什麼wpf可以把它們給我們轉換成對象呢?其實是靠這個東西 TypeConverter。

他的具體介紹 TypeConverter

接下在我們可以為我們之前寫的test這class添加一個TypeConverter。

建立一個類SayConverter然後繼承TypeConverter,重寫裡面的ConvertFrom方法,并且在原先的Say類下添加一個Msg的屬性。修改Execute,讓它彈窗提示Msg的值。并且在給Say類添加一個attr,值為

TypeConverter(typeof(SayConverter))

整體代碼如下:

public  class test
    {
        public test() {
            Name = "222";
            Say = new Say();
                 
        }
        public string Name { get; set; }
        public Say Say { get; set; }
    }
    [TypeConverter(typeof(SayConverter))]
    public class Say : ICommand
    {
        public string Msg { get; set; } = "sdf";
        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {
            return true;
        }

        public void Execute(object parameter)
        {
            MessageBox.Show(Msg);
        }
    }
    public class SayConverter : TypeConverter {
        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            return new Say
            {
                Msg=value.ToString()
            };
        }
    }
           

其中ConvertFrom就是将字元轉換成對象的一步。value就是我們在xaml裡面寫的值。

我們在去修改xaml,在window.datacontext的local:test後添加一個屬性 Say="lalala"

xaml的代碼如下:

<Window x:Class="WpfApp2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"

        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <!--xmlns:local="clr-namespace:WpfApp2"-->
    <Window.DataContext>
        <local:test xmlns:local="clr-namespace:WpfApp2" Say="lalala"/>
    </Window.DataContext>
    <Grid >
        <Button HorizontalAlignment="Center" Content="{Binding Name}" Command="{Binding Say}"/>
    </Grid>
</Window>
           

這個時候我們去點選按鈕觸發的彈窗就是lalala了。

當然這個東西用的不多,了解了解就可以了。用的更多的是在commond的Binding的Converter以及ConverterParameter,日後再聊。

繼續閱讀