天天看點

WPF整理-XAML建構背景類對象

原文: WPF整理-XAML建構背景類對象

1.XAML

接觸WPF的第一眼就是XAML---XAML是用來描繪界面的。其實不然!

"Actually, XAML has nothing to do with UI. It's merely a declarative way of constructing objects and setting their properties.”

XAML和UI一點關系也沒有,它僅僅是一種以聲明方式來建構對象,設定對象屬性的一種方式而已,和code behind file作用差不多。XAML這種聲明方式建構對象的好處是,程式員隻管聲明自己要什麼,至于如何建構則不需要考慮。

XAML對WPF來講,也不是必須的。我們可以輕松實作一個WPF工程,沒有任何XAML。  

XML也不是WPF才有,舉個反例如在WF中XAML被用來建構工作流。

2.XAML和編譯

"A XAML file is compiled by a XAML compiler that produces a binary version of the XAML, known as BAML. This BAML is stored as a resource inside the assembly and is parsed at runtime in the InitializeComponent call to create the actual objects. The result is bundled with the code behind file (the typical Window class is declared as partial, meaning there may be more source files describing the same class) to produce the final code for that class."

XAML檔案首先由XAML編譯器編譯成二進制的BAML,并以資源的形式存儲在程式集中,在運作時由InitializeComponent方法結合背景代碼來建構最終的對象。

3.通過XAML來建構背景類對象-Single Object

譬如我們定義一個背景類。如下:

class Book
    {
        public string Name { get; set; }
        public string Author { get; set; }
        public decimal Price { get; set; }
        public int YearPublished { get; set; }

    }      

我們如何在XAML中通路這個類呢?

1.添加一個XAML映射,code snip如下:

<Window x:Class="CreatingCustomTypeInXaml.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:local="clr-namespace:CreatingCustomTypeInXaml"      

如果不在同一個程式集需要加上";assembly=程式集名稱"。

2.這樣使用

<Grid>
        <Button  HorizontalAlignment="Left" Margin="129,82,0,0" VerticalAlignment="Top" Width="258" Height="107">
            <local:Book Name="WPF tutorial" Author="DebugLZQ" YearPublished="2013" Price="29.99"/>
        </Button> 
    </Grid>      

當然,為了使上面的代碼正常工作,我們需要為Book類重寫一個合适的ToString。

class Book
    {
        public string Name { get; set; }
        public string Author { get; set; }
        public decimal Price { get; set; }
        public int YearPublished { get; set; }

        public override string ToString()
     {
      return string.Format("{0} by {1}\npublished {2}",Name,Author,YearPublished);
        }
    }      

程式運作如下:

WPF整理-XAML建構背景類對象

----

又如,可以在MVVM中可以在View中為Window的DataContent指派ViewModel(雖不是最好的辦法):

<Window x:Class="AsynchronousBindingDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:AsynchronousBindingDemo"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>
    <Grid>
        <TextBlock Text="{Binding Text1, IsAsync=True}" FontSize="60" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Window>      

參考DebugLZQ後續博文:

MVVM: Improve MVVM Application Performance Using Framework Features View and ViewModel Mapping using MEFedMVVM

4.通過XAML來建構背景類對象-Collection Object

上面我們是在XAML中建構簡單的Single Object,如果我們需要建構一個數組,該如何做呢?

如,我們有如下一個類:

public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }      

現在我們需要用xaml建構這個類的數組。

我們在C#中新增一個類:

public class PersonList : List<Person>
    {
        
    }      

上面這個類的目的是用來包裝泛型List<Person>,因為泛型對象是無法再xaml中建構的。

其實,我們一般不用List,而是用ObservableCollection。請參考DebugLZQ後續博文:

WPF整理-Binding to a Collection

如下使用:

xmlns:local="clr-namespace:CreatingCustomTypeInXaml"      
<ListBox  DisplayMemberPath="Age">
            <ListBox.ItemsSource>
                <local:PersonList>
                    <local:Person Name="DebugLZQ1" Age="26"/>
                    <local:Person Name="DebugLZQ2" Age="26"/>
                </local:PersonList>
            </ListBox.ItemsSource>
        </ListBox>       

通常,我們會把XAML建構的對象放到Resource中。如下:

<Window.Resources>
        <local:PersonList x:Key="personList">
            <local:Person Name="DebugLZQ1" Age="26"/>
            <local:Person Name="DebugLZQ2" Age="26"/>
        </local:PersonList>
    </Window.Resources>      
<ListBox ItemsSource="{StaticResource personList}" DisplayMemberPath="Name"/>      

當然,List<int>、List<string>。。。。相同。

運作如下:

WPF整理-XAML建構背景類對象

附:MainWindow.xaml,MainWindow.xaml.cs

WPF整理-XAML建構背景類對象
WPF整理-XAML建構背景類對象
<Window x:Class="CreatingCustomTypeInXaml.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:CreatingCustomTypeInXaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:PersonList x:Key="personList">
            <local:Person Name="DebugLZQ1" Age="26"/>
            <local:Person Name="DebugLZQ2" Age="26"/>
        </local:PersonList>
    </Window.Resources>
    <StackPanel>
        <Grid>
            <Button  HorizontalAlignment="Left" Margin="129,82,0,0" VerticalAlignment="Top" Width="258" Height="107">
                <local:Book Name="WPF tutorial" Author="DebugLZQ" YearPublished="2013" Price="29.99"/>
            </Button>
        </Grid>
        <ListBox ItemsSource="{StaticResource personList}" DisplayMemberPath="Name"/>
        <ListBox  DisplayMemberPath="Age">
            <ListBox.ItemsSource>
                <local:PersonList>
                    <local:Person Name="DebugLZQ1" Age="26"/>
                    <local:Person Name="DebugLZQ2" Age="26"/>
                </local:PersonList>
            </ListBox.ItemsSource>
        </ListBox> 
    </StackPanel>
</Window>      

View Code

WPF整理-XAML建構背景類對象
WPF整理-XAML建構背景類對象
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace CreatingCustomTypeInXaml
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
    
    public class PersonList : List<Person>
    {
        
    }

}      

View Code

5.通過XAML建構---Static對象

WPF整理-XAML建構背景類對象

MainWindowTextSettings.cs如下:

using System.Windows.Media;

namespace StaticCliassInXamlDemo
{
    public class MainWindowTextSettings
    {
        public static double FontSize = 64;

        public static string StringValue = "Customer customized value";

        public static Brush ForeGround = new SolidColorBrush(Colors.Red);
    }
}      

MainWindow.xaml如下:

<Window x:Class="StaticCliassInXamlDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:oem="clr-namespace:StaticCliassInXamlDemo"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBlock Text="{x:Static oem:MainWindowTextSettings.StringValue}"
                    FontSize="{x:Static oem:MainWindowTextSettings.FontSize}"
                    Foreground="{x:Static oem:MainWindowTextSettings.ForeGround}"
                   TextTrimming="CharacterEllipsis"/>
    </Grid>
</Window>      

效果如下:

WPF整理-XAML建構背景類對象

希望對你有幫助~