天天看点

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,日后再聊。

继续阅读