WPF 数据绑定实例一
前言:
数据绑定的基本步骤:
(1)先声明一个类及其属性
(2)初始化类赋值
(3)在C#代码中把控件DataContext=对象;
(4)在界面设计里,控件给要绑定的属性{Binding 绑定类的属性}
原理:监听事件机制,界面改变有TextChanged之类的事件,所以改变界面可以同步修改到对象
想让普通对象实现数据绑定,需要实现INotifyPropertyChanged接口才能监听ProperChanged。具体代码如下显示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <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()
-
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 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,切记备注 加群,小编将会第一时间邀请你进群!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异