WPF程序设计指南:XAML

1. ML是XAML的一个应用。

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

  •  

    代码
    <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定义为字符串并解析

 代码

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  

代码
<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文件中输入如下内容:

代码
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的程序实例
代码
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的一部分,在其他地方还有代码。

  



posted on 2010-08-23 16:16  I过T  阅读(1710)  评论(0编辑  收藏  举报

导航