前言:
資料系結的基本步驟:
(1)先宣告一個類及其屬性
(2)初始化類賦值
(3)在C#代碼中把控制元件DataContext=物件;
(4)在界面設計里,控制元件給要系結的屬性{Binding 系結類的屬性}
原理:監聽事件機制,界面改變有TextChanged之類的事件,所以改變界面可以同步修改到物件
想讓普通物件實作資料系結,需要實作INotifyPropertyChanged介面才能監聽ProperChanged,具體代碼如下顯示:
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:
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="https://www.cnblogs.com/zls366/p/{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()
-
Thread.Sleep()是同步延遲,Task.Delay()是異步延遲,
-
Thread.Sleep()會阻塞執行緒,Task.Delay()不會,
-
Thread.Sleep()不能取消,Task.Delay()可以,
-
Task.Delay()實質創建一個運行給定時間的任務,Thread.Sleep()使當前執行緒休眠給定時間,
-
反編譯Task.Delay(),基本上講它就是個包裹在任務中的定時器,
-
Task.Delay()和Thread.Sleep()最大的區別是Task.Delay()旨在異步運行,在同步代碼中使用Task.Delay()是沒有意義的;在異步代碼中使用Thread.Sleep()是一個非常糟糕的主意,通常使用await關鍵字呼叫Task.Delay(),
-
我的理解: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,切記備注 加群,小編將會第一時間邀請你進群!
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/263167.html
標籤:WPF
