WPF程序设计指南:XAML

时间:2023-02-19 23:09:46

1. ML是XAML的一个应用。

  •       例1:一个合法片段,展现了控件以及element的嵌套层次结构:   

  •  

    WPF程序设计指南:XAMLWPF程序设计指南:XAML代码
        
        
        
    < StackPanel >
    < Button Foreground ="LightSeaGreen" FontSize ="24pt" > //指定attribute
    Hello, XAML! //指定property(content)
    </ Button >
    < Ellipse Fill ="Brown" Width ="200" Height ="100" /> //没有property
    < Button >
    < Image Source ="http://www.charlespetzold.com/PetzoldTattoo.jpg" Stretch ="None" />
    </ Button >
    </ StackPanel >
  •   指定WPF程序所需的命名空间,我们利用“xmlns”这个attribute来声明默认的XML命名空间。此命名空间会被应用于声明出现的element以及其下的每个孩子

           WPF命名空间指定方法: xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation

          例2:一个完整的XMAL文件内容:

    
    
    
< Button xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" // 指定WPF命名空间
Foreground ="LightSeaGreen" FontSize ="24pt" >
Hello, XAML!
</ Button >

2. 关于root element

  •      XML 文件只能有一个root element, 它可以是继承自FrameworkElement的任何类,但是不能是Window

 3. 如何在c#代码中解析XAML

  •     WPF程序使用XamlReader.Load将一段XAML转成一个对象,如果此XAML的根element具有子element,这些element会一并被转换,并放到visual tree中。

            但是,XamlReader.Load 不能直接接受字符串作为参数,只能接收Stream,或者一个XmlReader对象。

          例3:将XAML定义为字符串并解析

WPF程序设计指南:XAMLWPF程序设计指南:XAML 代码

   
   
   
using System;
using System.IO;
using System.Windows;
using System.Windows.Markup;
using System.Xml;

namespace Petzold.LoadEmbeddedXaml
{
public class LoadEmbeddedXaml : Window
{
[STAThread]
public static void Main()
{
Application app
= new Application();
app.Run(
new LoadEmbeddedXaml());
}
public LoadEmbeddedXaml()
{
Title
= " Load Embedded Xaml " ;

string strXaml =
" <Button xmlns='http://schemas.microsoft.com/ " +
" winfx/2006/xaml/presentation' " +
" Foreground='LightSeaGreen' FontSize='24pt'> " +
" Click me! " +
" </Button> " ;

StringReader strreader
= new StringReader(strXaml);
XmlTextReader xmlreader
= new XmlTextReader(strreader);
object obj = XamlReader.Load(xmlreader);

Content
= obj;
}
}
}

  如果需要获取此button并为其增加事件处理函数,可以如下处理:

 Button btn = (Button) XamlReader.Load(xmlReader);

   btn.Click+=ButtonClick;

  •   如果需要将XAML文件作为资源加载,需要将该XAML文件的Build Action设置为:Resource

          例4:在c#文件中加载并解析XAML文件。

          首先,在project中“Add New Item”,加入一个如下XML文件,命名为:LoadXamlResource  

WPF程序设计指南:XAMLWPF程序设计指南:XAML代码
   
   
   
< StackPanel xmlns = " http://schemas.microsoft.com/winfx/2006/xaml/presentation " >

< Button Name ="MyButton"
HorizontalAlignment
= " Center "
Margin
= " 24 " >
Hello, XAML
!
</ Button >

< Ellipse Width = " 200 "
Height
= " 100 "
Margin
= " 24 "
Stroke
= " Red "
StrokeThickness
= " 10 " />

< ListBox Width = " 100 "
Height
= " 100 "
Margin
= " 24 " >
< ListBoxItem > Sunday </ ListBoxItem >
< ListBoxItem > Monday </ ListBoxItem >
< ListBoxItem > Tuesday </ ListBoxItem >
< ListBoxItem > Wednesday </ ListBoxItem >
< ListBoxItem > Thursday </ ListBoxItem >
< ListBoxItem > Friday </ ListBoxItem >
< ListBoxItem > Saturday </ ListBoxItem >
</ ListBox >

</ StackPanel >

           右击该文件,选择Property,确定Build Action为 Resource

           在.cs文件中输入如下内容:

WPF程序设计指南:XAMLWPF程序设计指南:XAML代码
   
   
   
using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;

namespace Petzold.LoadXamlResource
{
public class LoadXamlResource : Window
{
[STAThread]
public static void Main()
{
Application app
= new Application();
app.Run(
new LoadXamlResource());
}
public LoadXamlResource()
{
Title
= " Load Xaml Resource " ;

Uri uri
= new Uri( " pack://application:,,,/LoadXamlResource.xml " );
Stream stream
= Application.GetResourceStream(uri).Stream;
FrameworkElement el
= XamlReader.Load(stream) as FrameworkElement;
Content
= el;

Button btn
= el.FindName("MyButton") as Button;

if (btn != null )
btn.Click
+= ButtonOnClick;
}
void ButtonOnClick( object sender, RoutedEventArgs args)
{
MessageBox.Show(
" The button labeled ' " +
(args.Source
as Button).Content +
" ' has been clicked " );
}
}
}

      代码分析:

        首先通过静态属性Application.GetResourceStream获取一个StreamResourceInfo对象,该对象包含一个Stream属性,便得到了XML资源。

        然后通过XamlReader.Load将资源转换成对象,再设为Window的Content, 变成窗口视觉树的一部分

          最后通过FindName方法在书中找出特定名称的element,也就是Button, 并添加相应的事件处理函数。

  •  例5:一个通过对话框加载XAML的程序实例
WPF程序设计指南:XAMLWPF程序设计指南:XAML代码
   
   
   
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Xml;

using Microsoft.Win32;

namespace Petzold.LoadXamlFile
{
public class LoadXamlFile : Window
{
Frame frame;

[STAThread]
public static void Main()
{
Application app
= new Application();
app.Run(
new LoadXamlFile());
}
public LoadXamlFile()
{
Title
= " Load XAML File " ;

DockPanel dock
= new DockPanel();
Content
= dock;

// Create button for Open File dialog.
Button btn = new Button();
btn.Content
= " Open File... " ;
btn.Margin
= new Thickness( 12 );
btn.HorizontalAlignment
= HorizontalAlignment.Left;
btn.Click
+= ButtonOnClick;
dock.Children.Add(btn);
DockPanel.SetDock(btn, Dock.Top);

// Create Frame for hosting loaded XAML.
frame = new Frame();
dock.Children.Add(frame);
}
void ButtonOnClick( object sender, RoutedEventArgs args)
{
OpenFileDialog dlg
= new OpenFileDialog();
dlg.Filter
= " XAML Files (*.xaml)|*.xaml|All files (*.*)|*.* " ;

if (( bool )dlg.ShowDialog())
{
try
{
// Read file with XmlTextReader.
XmlTextReader xmlreader = new XmlTextReader(dlg.FileName);

// Convert XAML to object.
object obj = XamlReader.Load(xmlreader);

// If it's a Window, call Show.
if (obj is Window)
{
Window win
= obj as Window;
win.Owner
= this ;
win.Show();
}

// Otherwise, set as Content of Frame.
else
frame.Content
= obj;
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, Title);
}
}
}
}
}

 4. XAML文件和code behind文件

  •  XAML文件中,WPF命名空间和XAML命名空间

   一般,我们会指定WPF element的命名空间为默认的命名空间:

            xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation

   WPF只是XAML的一种可能的应用方式,如果要使用XAML专用的element和attribute,需要第二个命名空间的声明:
    xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml

   如果需要自定义class,需要添加如下的命名空间:

    x:Class="MyNamespace.MyClassName"

 

  • 为支持定义在XAML文件中的控件和element,会需要一个code behind的c#文件:   
public namespace MyNamespace
{   
     public partial class MyClassName: Window  
      {    
              ...   
       }
}

      partial关键字意味着该文件只是此class的一部分,在其他地方还有代码。