對wpf 的入門記錄總結--數據綁定

在WPF中,微軟把數據綁定放到了非常重要的位置。
數據綁定是將數據從後臺代碼輸送到界面層的首選方法。當然,你也可以通過設置控件的屬性或者通過一個循環將數據項填充到ListBox的方法來顯示數據,但是,在數據源和目標界面元件之間建立一個綁定的方式是最純淨的。

控件綁定到另一個控件的屬性

<Window x:Class="數據綁定.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:數據綁定"
        mc:Ignorable="d"
        Title="MainWindow" Height="110" Width="300">
    <StackPanel Margin="10">
        <TextBox Name="txtValue" />
        <WrapPanel Margin="0,10">
            <TextBlock Text="Value: " FontWeight="Bold" />
            <TextBlock Text="{Binding Path=Text, ElementName=txtValue}" />
        </WrapPanel>
    </StackPanel>
</Window>

把第三個textblock的text屬性綁定到了第一個控件textbox上。
在這裏插入圖片描述
TextBox輸入文字,TextBlock會自動的更新。
在沒有使用挷定方法的時候,要做到這個功能,我們必需要監聽TextBox的事件並且在每次輸入文字時更新TextBlock。但是有了數據挷定功能之後,這個功能很容易被建立。

語法是:Binding Path=屬性名,path可以省略不寫。
ElementName=控件名

其含義: 綁定到某一個源上的某一個屬性。
所以這樣寫,感覺更符合邏輯。

<TextBlock Text="{Binding ElementName=txtValue, Path=Text}" />

想要綁定window的屬性,以上代碼可以這樣改寫:

<Window x:Class="數據綁定.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:數據綁定"
        mc:Ignorable="d"
        Title="MainWindow" Height="110" Width="300" Name="mywindow">
    <StackPanel Margin="10">
        <TextBox Name="txtValue" />
        <WrapPanel Margin="0,10">
            <TextBlock Text="Value: " FontWeight="Bold" />
            <TextBlock Text="{Binding Width,ElementName=mywindow}"  />
        </WrapPanel>
    </StackPanel>
</Window>

在這裏插入圖片描述
另外要想綁定,需要有一個源,要麼用ElementName顯示指定,如果不寫,可以考慮用DataContext屬性,它保存是綁定的默認源,默認值爲null。
以上代碼也可以這樣寫,省略ElementName=mywindow:

<Window x:Class="數據綁定.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:數據綁定"
        mc:Ignorable="d"
        Title="MainWindow" Height="110" Width="300" >
    <StackPanel Margin="10">
        <TextBox Name="txtValue" />
        <WrapPanel Margin="0,10">
            <TextBlock Text="Value: " FontWeight="Bold" />
            <TextBlock Text="{Binding Width}"/>
        </WrapPanel>
    </StackPanel>
</Window>

此時綁定源需要DataContext來指定,在cs代碼中

using System.Windows;

namespace 數據綁定
{
    /// <summary>
    /// MainWindow.xaml 的交互邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = this;
        }
    }
}

使用DataContext屬性, 可以節省手動命名每個源的麻煩,由於每個控件都有自己的DataContext屬性,所以可以這樣,比如在窗口上有一個全局DataContext,然後在一個Panel上指定一個特定的DataContext上,這個Panel所有的子控件都使用這個特定的DataContext。

DataContext既可以用代碼方式來指定,也可以用xaml來指定,比如第一個示例,可以改成這樣,稍顯羅嗦:

<TextBlock DataContext="{Binding ElementName=txtValue}" Text="{Binding Text}"/>

控件綁定到後臺變量

查了蠻久的資料,好像wpf的綁定是不能直接綁在單個變量上。
比如想綁一個整型變量,直接是做不到的,必須弄成class的形式,繼承一個接口。
把整型變量做成class中的一個屬性。

using System.ComponentModel;
using System.Threading;
using System.Windows;

namespace 數據綁定
{
    /// <summary>
    /// MainWindow.xaml 的交互邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        NUMBER n = new NUMBER();

        public MainWindow()
        {
            InitializeComponent();
            tb.DataContext = n;
            n.Num = 10;
                                
        }

        private void change(object sender, RoutedEventArgs e)
        {
            n.Num = 50;
        }
    }

    class NUMBER : INotifyPropertyChanged
    {
        int _num;

        public int Num
        {
            get { return _num; }
            set
            {
                if (this._num != value)
                {
                    this._num = value;
                    // 一旦執行了賦值操作說明其值被修改了,則立馬通過INotifyPropertyChanged接口告訴UI
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Num"));
                }
            }
        }
         
        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyPropertyChanged(string propName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }

    }
}

<Window x:Class="數據綁定.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:數據綁定"
        mc:Ignorable="d"
        Title="MainWindow" Height="110" Width="300" >
    <StackPanel Margin="10">
       
        <WrapPanel Margin="0,10">
            <TextBlock Text="Value: " FontWeight="Bold" />
            <TextBlock Name="tb" Text="{Binding Num}" />
           
        </WrapPanel>
        <Button Click="change">改變數字</Button>
    </StackPanel>
</Window>

在這裏插入圖片描述
在這裏插入圖片描述
可見比起第一種控件綁控件,爲了綁一個簡單的整型變量,第二種方式複雜太多,怪不得網上還是很多人用設置控件的屬性或者通過一個循環賦值來做。
微軟說很簡潔,我沒感覺出來,唯一的好處可能是第一次寫比較痛苦,每綁一個屬性,那個屬性就要寫一次。以後用起來就簡潔了吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章