1. 程式人生 > >WPF Binding學習(二)

WPF Binding學習(二)

ret 雙向綁定 rgs 點擊 離開 eve res owa 創建

  Binding作為數據的橋梁,連通業務邏輯層的對象(源對象)和UI的控件對象(目標對象)。在這座橋梁上,我們不僅可以控制在源對象與目標對象是雙向通行還是單向通行。還可以控制數據的放行時機,甚至可以在這座橋上搭建一些關卡用來轉換數據類型或者檢驗數據的正確性

我們先做一個最基本的例子,

創建一個"Student"類,這個類的實例將作為數據源來使用

 public class Student
    {
        private int _id;

        public int ID
        {
            get { return _id; }
            
set { _id = value; } } private string _name; public string Name { get { return _name; } set { _name = value; } } private int _age; public int Age { get { return _age; } set { _age = value; } } }

然後我們編寫我們的控件對象和創建邏輯對象

  <StackPanel Name="stack1">
        <TextBox Width="120" Text="{Binding Path=ID}" HorizontalAlignment="Left" Name="txt_ID"></TextBox>
        <TextBox  Width="120" Text="{Binding Path=Name}" HorizontalAlignment="Left" Name="txt_Name" ></TextBox>
        <TextBox  Text="
{Binding Path=Age}" Width="120" HorizontalAlignment="Left" Name="txt_Age"></TextBox> </StackPanel>

 public Student Stu; 
        public MainWindow()
        {
            InitializeComponent();
            Stu = new Student { ID = 1, Name = "狗娃", Age = 11 };
       //設置元素數據綁定對象 stack1.DataContext
= Stu; }

我們可以看到TextBox控件的Text是一個{Binding} 這就是數據綁定的關鍵字。然後Path屬性是需要綁定的屬性,然後我們運行就可以看到我們已經綁定OK。

上面我們是使用的界面進行綁定,其實我們還可以使用代碼對每一個控件進行綁定。現在我們將WPF界面中的綁定刪除掉

 <StackPanel Name="stack1">
        <TextBox Width="120"  HorizontalAlignment="Left" Name="txt_ID"></TextBox>
        <TextBox  Width="120"  HorizontalAlignment="Left" Name="txt_Name" ></TextBox>
        <TextBox  Width="120" HorizontalAlignment="Left" Name="txt_Age"></TextBox>
    </StackPanel>

然後我們使用代碼來進行控件綁定

  public Student Stu; 
  public MainWindow()
  {
            InitializeComponent();
            Stu = new Student { ID = 1, Name = "狗娃", Age = 11 };
            //創建Binding對象.
            Binding bindingID = new Binding() {Path = new PropertyPath("ID"),Source=Stu };
            //Binding構造參數可以直接傳入Path參數
            Binding bindingName = new Binding("Name") { Source = Stu };
            Binding bindingAge = new Binding("Age") { Source = Stu };

            //進行控件綁定(第一個參數是將綁定到哪個屬性,第二個參數是綁定對象)
            this.txt_ID.SetBinding(TextBox.TextProperty, bindingID);
            this.txt_Name.SetBinding(TextBox.TextProperty, bindingName);
            this.txt_Age.SetBinding(TextBox.TextProperty,bindingAge);
   }

可以看到使用代碼綁定需要創建Binding對象,然後使用控件的SetBinding方法進行綁定,但是郁悶的我們為了綁定這三個屬性要寫這麽多的代碼.所以使用哪種方式綁定看需求來使用.

接下來我們看雙向綁定,其實上面那個我們已經實現了雙向綁定,我們先做一個例子測試

創建一個測試TextBox並綁定數據ID

<TextBox Width="120"  HorizontalAlignment="Left"  Name="txt_IDTest"></TextBox>
 Binding bindingTestID = new Binding() { Path = new PropertyPath("ID"), Source = Stu };
 this.txt_IDTest.SetBinding(TextBox.TextProperty, bindingTestID);

然後我們在更改txt_ID屬性值後光標離開就可以看到txt_IDTest的值也隨之改變了。這是因為TextBox默認是雙向綁定的,所以可以改變,但是如果我們不是使用控件改變的值呢,接下來做個這樣例子.在界面上添加一個Button按鈕,並添加點擊事件

<Button Content="Button" Width="120" HorizontalAlignment="Left" Click="Button_Click"/>

 private void Button_Click(object sender, RoutedEventArgs e)
        {

            Stu.ID++;
        }

我們在點擊事件中只做了一件事,那就是讓Stu的編號加1,但是運行會發現並沒有改變。那麽該怎麽做呢。

我們需要在綁定源類型(Student類型)實現INotifyPropertyChanged接口

public class Student:INotifyPropertyChanged
    {
        private int _id;

        public int ID
        {
            get { return _id; }
            set { _id = value; MyPropertyChanged(nameof(ID)); }
        }

        private string _name;

        public string Name
        {
            get { return _name; }
            set { _name = value; MyPropertyChanged(nameof(Name)); }
        }

        private int _age;

        public event PropertyChangedEventHandler PropertyChanged;

        public int Age
        {
            get { return _age; }
            set { _age = value; MyPropertyChanged(nameof(Age)); }
        }
        private void MyPropertyChanged(string name)
        {
           if(PropertyChanged!=null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }

然後此時我們就可以實現改變了.

2.綁定更新的計時

但是我們往往需要在輸入後就讓它立即改變,所以我們需要設置Binding對象中的UpdateSourceTrigger屬性,

  Binding bindingID = new Binding() { Path = new PropertyPath("ID"), Source = Stu, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged};

UpdateSourceTrigger枚舉值有4個

  • Default:綁定目標屬性的默認值
  • PropertyChanged:每當綁定目標屬性發生改變時,都會更新數據源
  • LostFocus:每當綁定目標元素失去焦點時,都會更新綁定源
  • Explicit:僅在調用System.Windows.Data.BindingExpression.UpdateSource 方法時更新綁定源。

因此我們將UpdateSourceTrigger的屬性值改成PropertyChanged即可

3.設置單項和雙向綁定

剛才使用了TextBox的雙向綁定,但是比如我們現在不需要雙向綁定,我們只需設置Mode屬性即可

 Binding bindingID = new Binding() { Path = new PropertyPath("ID"), Source = Stu,Mode = BindingMode.OneTime, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged};

BindingMode枚舉有5個值

  • TwoWay:導致更新源屬性或目標屬性時自動更新另一方
  • OneWay:在更改綁定源(源)時更新綁定目標(目標),如果綁定的控件為隱式只讀,則此類型的綁定適用。如果無需監視目標屬性的更改 則使用 System.Windows.Data.BindingMode.OneWay 綁定模式可避免 System.Windows.Data.BindingMode.TwoWay

    綁定模式的系統開銷。

  • OneTime:這是實質上是 System.Windows.Data.BindingMode.OneWay 綁定的一種簡化形式,它在源值不更改的情況下提供更好的性能。
  • OneWayToSource:在目標屬性更改時,更新源屬性。
  • Default: 使用綁定目標的默認 System.Windows.Data.Binding.Mode 值

WPF Binding學習(二)