XAML基础(一)

     1.0 XAML是啥?     

   XAML(eXtensible Application Markup Language,可 扩展应用 程序标记语言) 是一种声明性的XML语法 ,像WPF,WF或者Silverlight应用程序通常需要 XAML。Xaml元 素通常映射到,NET类 。 这并不是一个严格的要求 ,但通常都是如此。


  1.1 元素 映射到 .net对 象上

  一个控制台Demo,需 要引用程序集 PresntationFramework、 PresentatioCore、 WhdowBase和 system.Xaml。 

 1 using System;  2 using System.Windows;  3 using System.Windows.Controls;  4 
 5 namespace ConsoleApplication1  6 {  7     class Program  8  {  9  [STAThread] 10         static void Main(string[] args) 11  { 12             var b = new Button { Content="Click Me!" }; 13             var w = new Window { Title="Code Demo",Content=b }; 14 
15             var app = new Application(); 16  app.Run(w); 17  } 18  } 19 }
View Code

同样的效果由XAML实现,代码如下:

 1 <Window x:Class="XMAL.MainWindow"
 2  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6  xmlns:local="clr-namespace:XMAL"        
 7  mc:Ignorable="d"
 8  Title="XAML Demo" Height="350" Width="525">
 9     <StackPanel x:Name="stackPanel1">
10         <Button Content="Click Me!"></Button>
11         <!--<Button Content="Click Me!" Height="200"> 12  <Button.Background> 13  <LinearGradientBrush StartPoint="0.5,0.0" EndPoint="0.5,1.0"> 14  <GradientStop Offset="0" Color="Yellow"></GradientStop> 15  <GradientStop Offset="0.3" Color="Orange"></GradientStop> 16  <GradientStop Offset="0.7" Color="Red"></GradientStop> 17  <GradientStop Offset="1.0" Color="DarkRed"></GradientStop> 18  </LinearGradientBrush> 19  </Button.Background> 20  </Button>-->
21         <!--<Button Name="button1" Content="Button 1" Margin="5" /> 22  <Button x:Name="button2" Margin="5" Click="OnButton2"> 23  <ListBox Name="listBox1"> 24  <Button x:Name="innerButton1" Content="Ihner Button 1" Margin="4" Padding="4" Click="OnInner1" /> 25  <Button x:Name="innerButton2" Content="Inner Button 2" Margin="4" Padding="4" Click="OnInner2" /> 26  </ListBox> 27  </Button>-->
28         <!--<DockPanel> 29  <Button Content="Top" DockPanel.Dock="Top" Background="Yellow"></Button> 30  <Button Content="Top" DockPanel.Dock="Left" Background="Blue"></Button> 31  </DockPanel>-->
32     </StackPanel>
33 </Window>
View Code

当然Application的实例也可以在XAML中定义

1 <Application x:Class="XMAL.App"
2  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4  xmlns:local="clr-namespace:XMAL"
5  StartupUri="MainWindow.xaml">
6     <Application.Resources>         
7     </Application.Resources>
8 </Application>
View Code 

  1.2 使用自定义.net类

  首先定义一个简单的Person类,包含2个属性,FirstName和LastName;

 1 namespace XMAL  2 {  3     class Person  4  {  5         public Person()  6  {  7             FirstName = "one";  8             LastName = "two";  9  } 10 
11         public string FirstName { get; set; } 12         public string LastName { get; set; } 13 
14         public override string ToString() 15  { 16             return string.Format("{0}, {1}", FirstName, LastName); 17  } 18  } 19 }
View Code

然后在XAML文件中引入Person类的命名,空间起别名为LocalXAML基础(一)_第1张图片可以看到有很多的.net命名空间可以引用,引入明明空间后,写XAML代码 

1    <ListBox>
2             <Local:Person FirstName="12" LastName="34"></Local:Person>
3         </ListBox>
View Code

运行程序,ToString()方法就把对象的值显示在列表中。(如果没有TOstring方法则显示的是这个对象)

  1.3 把特性用作属性

  只要属性的类型可以表示为字符 串,或者可以把字符串转换为特属性型,就可以把属性设置为属性。 下面 的代码段用特性设置 了 Button元 素 的 Content和Backgromd属 性 。 因为 Content属性的类型是 object,所以可 以接受字符串 。 Background属性的类型是 Brush,Brush类型把 BrushConvener类定义为一个转换器类型,这个类用 Typeconvmer特性进行注解 。 BrushConvener使用 一个颜色列表,从 ConverFormString()方法中返回一个SolidColorBrush<Button Content="Click Me!" Background="Aqua"></Button>

  1.4 把特性用作元素

  总是可 以使用 元素语法给属性提供值 。 Button类 的 Backgromd属性可以用子元素 Button.Background设 置。 这样,可以把比较复杂的画笔应用于这个属性,

2 依赖属性

 2.1 创建依赖属性 

  WPF使 用 依赖属性完成数据绑定、 动画、 属性变更通知 、 样式化等 。 对于数据绑定,绑 定到.NET属性源上 的 t1I元 素 的属性必须是依赖属性 。依赖属性和.net的属性一样也包含Get和Set访问器,但是依赖属性调用了基类DependencyObject的GetValue()和SetValue()方法,这2个方法都需要一个参数,参数为属性名+Proprty,基类通过Register()方法注册属性,上demo

 1 public class DemoDependencyObject : DependencyObject  2  {  3         public static readonly DependencyProperty ValueProperty =
 4             DependencyProperty.Register("Value", typeof(int), typeof(DemoDependencyObject));  5 
 6         public int Value  7  {  8             get { return (int)GetValue(ValueProperty); }  9             set { SetValue(ValueProperty, value); } 10  } 11     }
DemoDependencyObject

  2.2强制值回掉
  依赖属性支持强制检查,由此来判断属性的值是否有效,即Register方法的第4个构造,传递一个PropertyMetadatalei类,在CoerValue方法中写入自己的额Code;

 1  public static readonly DependencyProperty ValueProperty =
 2             DependencyProperty.Register("Value", typeof(int), typeof(DemoDependencyObject),new PropertyMetadata(0,null, CoerValue));  3         private static object CoerValue(DependencyObject elemnet, object value)  4  {  5             //your code  6             //int newValue = (int)value;  7             //MyDependencyObject control = (MyDependencyObject)elemnet;  8             //newValue = Math.Max(control.Minimun, Math.Min(control.Maximun, newValue));  9             //return newValue;
10         }
View Code

   2.3 值变更回掉和事件

  为 了 获 得 值 变 更 的信 息 ,依 赖 属 性还支 持值 变 更 回 调 。 在 属 性 值 发 生 变 化 时调 用 的DependencyProperty.Register()方 法中,可 以添加一个 DependencyPropeGhanged事件处理程序 。

1 public static readonly DependencyProperty ValueProperty =
2             DependencyProperty.Register("Value", typeof(int), typeof(MyDependencyObject), new PropertyMetadata(0, OnValueChanged, CoerValue)); 3 
4         public static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 5  { 6             int oldValue = (int)args.OldValue; 7             int newValue = (int)args.NewValue; 8             ///your code
9         }
View Code

3 附加属性 

1  <DockPanel>
2         <Button Content="Top" DockPanel.Dock="Top" Background="Yellow"></Button>
3         <Button Content="Left" DockPanel.Dock="Left" Background="Blue"></Button>
4     </DockPanel>
View Code  

纳尼,什么鬼,DockPanel.Dock是Button的属性?Button并没有Dock属性,他是通过DockPanel空间附加给Button,为其正起名曰附加属性。附加属性的定义和依赖属性很相似,它是调用RegisterAttached()方法,

 1  class MyAttachedPropertyProvide : DependencyObject  2  {  3         public static readonly DependencyProperty myPropertyProperty = 
 4             DependencyProperty.RegisterAttached("MyProperty", typeof(int), typeof(MyAttachedPropertyProvide));  5         public int MyProperty  6  {  7             get { return (int)GetValue(myPropertyProperty); }  8             set { SetValue(myPropertyProperty,value); }  9  } 10         public static void SetMyProperty(UIElement element,int value) 11  { 12  element.SetValue(myPropertyProperty,value); 13  } 14         public static int GetMyProperty(UIElement element 15  { 16            return (int)element.GetValue(myPropertyProperty); 17  } 18     }
MyAttachedPropertyProvide

 似乎DockPanel.Dock属性只能添加到DockPanel中的控件上,实际上,附加属性可以添加到任何元素上,但是无法识别这个属性值。 

 

 1 <Window x:Class="XMAL.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:Local="clr-namespace:XMAL"      
 7         mc:Ignorable="d"
 8         Title="XAML Demo" Height="350" Width="525">
 9     <Grid x:Name="grid">
10         <Grid.RowDefinitions>
11             <RowDefinition Height="auto"></RowDefinition>
12             <RowDefinition Height="auto"></RowDefinition>
13             <RowDefinition Height="*"></RowDefinition>
14         </Grid.RowDefinitions>
15         <Button Grid.Row="0" x:Name="button1" Content="Button1"></Button>
16         <Button Grid.Row="0" x:Name="button2" Content="Button2"
17                 Local:MyAttachedPropertyProvide.MyProperty="5"></Button>
18         <ListBox Grid.Row="2" x:Name="list1"></ListBox>
19     </Grid>
20 </Window>
View Code

 

C#的使用

1  public MainWindow()
2         {
3             InitializeComponent();
4 
5             MyAttachedPropertyProvide.SetMyProperty(button1, 44);
6 
7             list1.Items.Add(MyAttachedPropertyProvide.GetMyProperty(button1));
8         }       
View Code

 

4 标记扩展

通过标记扩展 ,可 以扩展 XAML的 元素或特性语法 。 如果 XML特 性包含花括号,就表示这是标记扩展 的一个符号 。 特性的标记扩展常常用 作简写记号,而 不再使用 元素 。如StaticResourcrce
要创 建标记扩展 ,可 以定义一个派生 自基类 MarkupExtension的 类 。 大 多数标记扩展名 都有Extension后缀,有 了 自定义标记扩展后 ,就只需重写ProvideeValue()方 法 ,它 返回扩展的值 .返回的类型用MarkupExtensionReturnType注解。

 

 1   public enum Operation { Add, Subtract, Multiply, Divide }
 2     [MarkupExtensionReturnType(typeof(string))]
 3     public class CalculatorExtension : MarkupExtension
 4     {
 5         public CalculatorExtension() { }
 6 
 7         public double X { get; set; }
 8         public double Y{ get; set; }
 9         public Operation operation { get; set; }
10         public override object ProvideValue(IServiceProvider serviceProvider)
11         {
12             IProvideValueTarget provideValue = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
13             if (provideValue != null)
14             {
15                 var host = provideValue.TargetObject as FrameworkElement;
16                 var prop = provideValue.TargetObject as DependencyProperty;
17             }
18             double result = 0;
19             switch (operation)
20             {
21                 case Operation.Add:
22                     result = X + Y;
23                     break;
24                 case Operation.Subtract:
25                     result = X - Y;
26                     break;
27                 case Operation.Multiply:
28                     result = X * Y;
29                     break;
30                 case Operation.Divide:
31                     result = X / Y;
32                     break;
33                 default:
34                     throw new ArgumentException("error");
35             }
36             return result.ToString();
37         }
38     }
CalculatorExtension

 

 1 <Window x:Class="XMAL.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:Local="clr-namespace:XMAL"      
 7         mc:Ignorable="d"
 8         Title="XAML Demo" Height="350" Width="525">
 9     <StackPanel>
10         <TextBlock Text="{Local:Calculator operation=Add,X=3,Y=4}"/>
11         <TextBlock>
12             <TextBlock.Text>
13                 <Local:CalculatorExtension>
14                     <Local:CalculatorExtension.operation>
15                         <Local:Operation>Multiply</Local:Operation>
16                     </Local:CalculatorExtension.operation>
17                     <Local:CalculatorExtension.X>7</Local:CalculatorExtension.X>
18                     <Local:CalculatorExtension.Y>11</Local:CalculatorExtension.Y>
19                 </Local:CalculatorExtension>
20             </TextBlock.Text>
21         </TextBlock>
22     </StackPanel>
23 </Window>
View Code

5 XAML定义的标记扩展

用 XAML定 义 的其他标记扩展有 TypeExtension(x:Type) ,它 根据字符 串输入返 回类 型 ;NullExtension(x:Null),它 可以用于在 XAML 中把值设置为空;StaticExtension(x:static),它 可调用类的静态成员。 

未完待续。。。。。。。

 

你可能感兴趣的:(XAML基础(一))