2014年12月25日 星期四

WPF Binding (二) DataBinding 資料繫結

在 Wpf 中,繫結來源除了控制項之間的繫結外,在程式中的任何物件、集合都可作為繫結來源。以下用一個學生物件來展現物件與控制項之間的繫結。
  • c# Student 類別

public class Student
{
    public string Name { get; set; }
    public int Number { get; set; }
}





  • xaml
<Window x:Class="SimpleDataBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SimpleDataBinding"        Title="MainWindow" Height="124" Width="174">
    <Window.Resources>
        <local:Student x:Key="student"
                       Name="王小明"
                       Number="9"/>
    </Window.Resources>
    <StackPanel Orientation="Vertical">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="學生姓名:" Margin="5"/>
            <TextBlock Text="{Binding Source={StaticResource student}, Path=Name}" Margin="5"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="座號:" Margin="5"/>
            <TextBlock Text="{Binding Path=Number,Source={StaticResource student}}" Margin="5"/>
        </StackPanel>
    </StackPanel>
</Window>
  要把類別 Student 加入到 xaml 中,一開始是在 Window 標籤中宣告 Student  物件命名空間的參考 local,local 是自訂名稱,而後面要再連接 SimpleDataBinding 的 NameSpace,最後在 Window.Resource 標籤中加入Student 物件的邏輯資源。以上 xaml 的寫法是使用 Static Resources 來處理資料繫結,還可使用DataContext 來處理資料繫結。如下:


<Window x:Class="SimpleDataBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SimpleDataBinding"
        Title="MainWindow" Height="124" Width="174">
    <Window.DataContext>
        <local:Student Name="王小明"
                       Number="9"/>
    </Window.DataContext>
    <StackPanel Orientation="Vertical">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="學生姓名:" Margin="5"/>
            <TextBlock Text="{Binding Path=Name}" Margin="5"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="座號:" Margin="5"/>
            <TextBlock Text="{Binding Path=Number}" Margin="5"/>
        </StackPanel>
    </StackPanel>
</Window>




  以上的 xaml 變動不大,把原本 Window.Resources 標籤換成 Window.DataContext 標籤,而在控制項資料繫結方面,將原本 Source 屬性給拿掉。



當然也有個疑問,是否可以在 local:Student 標籤中不給屬性 Name 和 Number 值呢?當然是可以的,例如直接在 Student 類別中的建構子給予 Name 和 Number 一個值,或在另一個 StudentInfo 類別中建立一個 Student 物件。





  • C# Student.cs


public class Student
{
    public string Name { get; set; }
    public int Number { get; set; }

    public Student()
    {
        this.Name = "王小明";
        this.Number = 9;
    }
}





  • C# 從 StudentInfo 建立 Student 物件


public class StudentInfo
{
    public Student student;

    public string Name
    {
        get { return student.Name; }
        set { student.Name = value; }
    }
    public int Number
    {
        get { return student.Number; }
        set { this.student.Number = value; }
    }

    public StudentInfo()
    {
        this.student = new Student();
        this.student.Name = "王小明";
        this.student.Number = 9;
    }
}





  • xaml 變更 DataContext 繫結來源


<Window.DataContext>
    <local:StudentInfo/>
</Window.DataContext>

以上寫法是把 Student 物件放在 Window.DataContext 標籤中,如果單純使用程式碼的寫法,則如下所示:



  • C#

namespace SimpleDataBinding
{
    /// <summary>
    /// MainWindow.xaml 的互動邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Student student = new Student() { Name = "王小明", Number = 9 };
            this.DataContext = student;
        }
    }

    public class Student
    {
        public string Name { get; set; }
        public int Number { get; set; }
    }


}


  • xaml

<Window x:Class="SimpleDataBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="117" Width="133">

    <StackPanel Orientation="Vertical">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="學生姓名:" Margin="5"/>
            <TextBlock Text="{Binding Path=Name}" Margin="5"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="座號:" Margin="5"/>
            <TextBlock Text="{Binding Path=Number}" Margin="5"/>
        </StackPanel>
    </StackPanel>
</Window>



  Static Resources 和 DataContext 的區別在於,當有多個目標的繫結來源都來自同一個資源時,使用 DataContext 無非是最好的作法,既可避免造成程式碼冗長,也容易維護。

沒有留言:

張貼留言