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的命名空间
在创建一个页面的时候,编辑器会给我添加上默认的几个空间,如下图:
这些都是默认导入的空间,你能够在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; }
}
}
在这里申明是代表在这个父节点中引入这个空间。这样他的所有子节点,就都可以使用这些空间里面的类。如果只想在单独的一个节点中申明的话可以这样子写。
<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>
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>
当然啦,其实这是一个假象,因为他生成的并不是4个item。而是一个item中包含了4个sdf以及3个空格。
他省略的是listviewitem的对象的申明。
我们修改下代码
<ListBox>
<TextBlock Text="sdf"/>
<TextBlock Text="sdf"/>
<ListViewItem>
<TextBlock Text="sdf"/>
</ListViewItem>
<ListViewItem>
sdf
</ListViewItem>
</ListBox>
效果如下:
看吧,效果是一样的
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,日后再聊。