WPF 數據綁定實例一

前言:

  數據綁定的基本步驟:express

(1)先聲明一個類及其屬性微信

(2)初始化類賦值異步

(3)在C#代碼中把控件DataContext=對象;async

(4)在界面設計裏,控件給要綁定的屬性{Binding 綁定類的屬性}ide

原理:監聽事件機制,界面改變有TextChanged之類的事件,因此改變界面能夠同步修改到對象this

想讓普通對象實現數據綁定,須要實現INotifyPropertyChanged接口才能監聽ProperChanged。具體代碼以下顯示:spa

  class Person:INotifyPropertyChanged
    {
        private int age;
 
        public int Age
        {
            get
            {
                return age;
            }
            set
            {
                this.age = value;
                if (PropertyChanged != null)
                {
                   PropertyChanged(this,
                       new PropertyChangedEventArgs("Age"));
                }
            }
        }
}

  

BindingMode枚舉值
名稱 說明
OneWay 當源屬性變化時更新目標屬性
TwoWay 當源屬性變化時更新目標屬性,當目標屬性變化時更新源屬性
OneTime 最初根據源屬性設置目標屬性,其後的改變會忽略。
OneWayToSource 與OneWay類型類似,但方向相反。
Default 此類綁定依賴於目標屬性



UpdateSourceTrigger
名稱 說明
Default 默認值,與依賴屬性有關
Explicit 必須在顯示地調用BindingExpression.UpdateSource的狀況下才更新源。
LostFocus 控件失去焦點的時候更新源值
PropertyChanged 綁定的目標值改變時更新。

實例運行後界面以下:線程

 

 MainWindow.xaml設計

<Window x:Class="WpfApp1.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:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="600" Width="800">
    <StackPanel>
        <TextBlock Text="Student ID:" FontWeight="Bold" Margin="5"/>
        <TextBox Name="textBoxId" Margin="5" Text="{Binding Id,Mode=TwoWay}"/>
        <TextBlock Text="Student Name:" FontWeight="Bold" Margin="5"/>
        <TextBox Name="textBoxName" Margin="5" Text="{Binding Name,Mode=TwoWay}"/>
        <TextBlock Text="Student List:" FontWeight="Bold" Margin="5"/>
        <ListBox Name="listBox1" Height="110" Margin="5" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Path=Id}" Width="30"/>
                        <TextBlock Text="{Binding Path=Name}" Width="60"/>
                        <TextBlock Text="{Binding Path=Age}" Width="30"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <ListBox Name="listBox2"  Height="80" ItemsSource="{Binding Student}" DisplayMemberPath="Id" Margin="5"/>
        <Slider Name="slider1" MinHeight="25" Value="{Binding Id}"/>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"></RowDefinition>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Button Grid.Column="0" Content="Action" FontSize="40" Name="btnCtrl1" Height="80" Margin="5" Click="BtnCtrl1_Click"/>
            <Button Grid.Column="1" Content="Action" FontSize="40" Name="btnCtrl2" Height="80" Margin="5" Click="BtnCtrl2_Click"/>
        </Grid>
    </StackPanel>
</Window>

  

首先解釋下C#中的Task.Delay()和Thread.Sleep() 

  1. Thread.Sleep()是同步延遲,Task.Delay()是異步延遲。orm

  2. Thread.Sleep()會阻塞線程,Task.Delay()不會。

  3. Thread.Sleep()不能取消,Task.Delay()能夠。

  4. Task.Delay()實質建立一個運行給定時間的任務,Thread.Sleep()使當前線程休眠給定時間。

  5. 反編譯Task.Delay(),基本上講它就是個包裹在任務中的定時器。

  6. Task.Delay()和Thread.Sleep()最大的區別是Task.Delay()旨在異步運行,在同步代碼中使用Task.Delay()是沒有意義的;在異步代碼中使用Thread.Sleep()是一個很是糟糕的主意。一般使用await關鍵字調用Task.Delay()。

  7. 個人理解:Task.Delay(),async/await和CancellationTokenSource組合起來使用能夠實現可控制的異步延遲。


MainWindow.xaml.cs

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows;

namespace WpfApp1
{
    /// <summary>
    /// MainWindow.xaml 的交互邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        public ObservableCollection<Student> stuList;
        public MainWindow()
        {         
            InitializeComponent();
            this.DataContext = new Student() { Name="111", Id =1 };
            Task.Run(async() =>  //開啓異步線程task
            {
                await Task.Delay(3000); //延時3秒
                Dispatcher.Invoke((Action)delegate //線程中主界面顯示須要用委託,否則此次賦值,在界面不更新
                {
                    this.DataContext = new Student() { Name = "222", Id = 2 };
                });
            });          
            this.DataContext = new Student() { Name = "333" , Id = 3 };
        }

        private void BtnCtrl1_Click(object sender, RoutedEventArgs e)
        {
            Student stu = new Student() { Id = 4, Name = "Jon", Age = 29 }; //實例化一個Student類 並給類成員賦值
            this.DataContext = stu;//將實例化得對象傳給DataContext
        }
        private void BtnCtrl2_Click(object sender, RoutedEventArgs e)
        {
            ObservableCollection<Student> stuList = new ObservableCollection<Student>() //具備通知屬性的list
            {
             new Student() { Id=5, Name="Tim", Age=29 },
             new Student() { Id=6, Name="Tom", Age=28 },
             };
            this.listBox1.ItemsSource = stuList;

            this.listBox2.ItemsSource = stuList;
            this.listBox2.DisplayMemberPath = "Name";
            this.DataContext = stuList;
        }
    }
    public class Student : INotifyPropertyChanged  //建立一個繼承自INotifyPropertyChanged的類Student
    {

        private string name;

        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                if (this.PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("Name")); //給Name綁定屬性變動通知事件
                }
            }
        }

        private int id;

        public int Id
        {
            get { return id; }
            set
            {
                id = value;
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Id"));//給Id綁定屬性變動通知事件
                }
            }
        }

        private int age;

        public int Age
        {
            get { return age; }
            set
            {
                age = value;
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Age"));//給Age綁定屬性變動通知事件
                }
            }
        }

        public int ID { get; internal set; }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}

  

想了解更多C#知識,請掃描下方二維碼

 

 

需加微信交流羣的,請加小編微信號z438679770,切記備註 加羣,小編將會第一時間邀請你進羣!

相關文章
相關標籤/搜索