WPF行为模式
如何让界面上执行计算逻辑 1+1=2
public TextBoxModel TB1Model { get; set; } = new TextBoxModel();
public TextBoxModel TB2Model { get; set; } = new TextBoxModel();
<StackPanel>
<TextBlock Text="{Binding TB1Model.Text}" Margin="10" VerticalAlignment="Top" Background="Orange"/>
<TextBlock Text="{Binding TB2Model.Text}" Margin="10" VerticalAlignment="Top" />
</StackPanel>
<TextBlock>点击</TextBlock>
改为
<TextBlock Text="{Binding BModel.Text}"></TextBlock>
显示结果
private void ButtonClick(object obj) { //业务逻辑代码 //获取两个文本框的值 string str1 = TB1Model.Text; string str2 = TB2Model.Text; //判断两个文本框是否为空 if (string.IsNullOrEmpty(str1) || string.IsNullOrEmpty(str2)) { //弹出提示框 //MessageBox.Show("请输入两个文本框的值!"); } else { BModel.Text = str1 + str2; } }
执行并没有变化
1、通知属性的定义
按钮需要实现一个接口
INotifyPropertyChanged
添加引用、实现接口:辅助操作快捷键ALT+Enter,出来提示,再Enter确认
Text只要是要通知到界面上的属性 都需要调用事件
propfull快速构建属性getset
public class ButtonModel : INotifyPropertyChanged { public event PropertyChangedEventHandler? PropertyChanged; public int Width { get; set; } = 200; //public string Text { get; set; } = "Button"; private string _text = "Button"; public string Text { get { return _text; } set { _text = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Text")); } } }
1、第一次加载的时候就会检查绑定,默认显示到前台,不需要通知属性
2、界面输入新的值,数据会反馈到数据模型中,不需要再额外通知属性处理数据模型,
因为已经通过上下文DBContext关联,只要一变化,就会写入到实例的属性当中去
唯一的属性,一对一,已经明确限制了
3、当业务逻辑计算完成之后,写入到界面,
界面是运行时状态,没办法再次获取数据,不通知它它不知道
只知道第一次牵手关联的值,后面再变化没有任何感知
需要再给一个信号
不可能前端不停刷新监控值
是一个被动的接收,通过PropertyChanged事件通知,才会有变化
计算后的值有可能在不同界面上有绑定,要指定到底更新哪一个
实时变化必须要写

两个问题
1、为什么界面第一次加载的时候有数据
2、为什么界面数据输入变化之后不需要通知后端
3、为什么计算完之后需要通知
model是我们自己建的要自己PropertyChanged
底层其实是有一个队列的,绑定表达式,实际上是告诉我们框架 通知订阅了我变化的属性的控件都更新一下
界面上操作的控件是唯一的,可以找到哪个属性
属性不一定只绑定一个控件 ,如果不指定,无法找到具体是哪个控件,因为是一对多
为什么要这样操作?
要进行View和业务逻辑的分离,切割解耦合
只是改下控件的基本需求 ,只改界面就可以完成,不需要再牵扯业务逻辑
2、耗时操作
用一个多线程
Task.Run(() => { Task.Delay(1000).GetAwaiter().GetResult();//等待1秒 BModel.Text = str1 + str2; });
传统模式:this.控件.text 这样会出现跨线程问题
现在WPF这种方式没有跨线程问题
3、死循环
Task.Run(() => { while (true) { //BModel.Text = str1 + str2; //Task.Delay(1000).GetAwaiter().GetResult();//等待1秒 BModel.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); } });
10毫秒,甚至不需要等待,都可以让界面显示结果,拖动窗口也可以,没有影响
传统模式刷新率达不到这么高,无法拖动主窗体,线程被阻塞
要包裹一层,把耗时操作放到UI线程中处理
刷新率太高还是会影响界面的刷新,刷新不出来,更不要说拖动了
通过数据模型绑定的方式,让界面被动的改变
而不是直接操控view界面
而是隔山打牛,通过数据模型
中间是订阅发布的过程
这就是WPF整体完整入门级的思路
思维转变
答疑
1、
Task.Delay(1000).GetAwaiter().GetResult();和Thread。Sleep区别
Task是ThreadPool升级本,。在实现结果上差不多
Thread一般来讲是针对当前线程的
Task是针对当前任务的。其实也是一个线程
2、GetAwaiter().GetResult();是为了等待,异步等待
UI线程的Sleep界面肯定就卡住了
Task虽说后面逻辑不会走,但是不会卡线程 ,是异步的形式
同一下
Task.Run(async() => { while (true) { await Task.Delay(10); BModel.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); } });
都是异步等待的方式实现
3、Command属性如何处理不同的事件?
左键、右建、中建的基本事件都可以绑定
任意对象的任意事件都可以绑定
现在是命令属性的方式处理
还可以VM中的方法也可以绑定,不同的绑定方式
button的Command就是左键单击
4、Winform和WPF性能之争
Winform是直接操控控件
WPF是通过数据模型操控界面是有一定性能损失,需要额外的代码执行
界面渲染层面,WPF是有一定的性能优势的
资源占用,Winform对象是通过独立性的句柄进行渲染的
WPF渲染方式不一样 是通过GPU,GLX,插件绘制的,界面是平面的
不需要通过对象接收事件 ,所有对象通过窗口VM传进来的
性能差别不大
4.5之后的WPF是有很大的改善的,代码重构。性能提升
之前资源占用,稍微耗时一些,电脑配置差一些,win7,vist,耗费资源
win10都有很大的改善
5、TreeView和DataGrid停车场有应用
实战更有针对性
6、IDE快捷键编译器来的
选项-键盘-

7、鼠标点击,click,通过buttonDown绑定的
8、Binding BModel 是双向绑定
Mode=“TwoWay”表示可以双向通讯 ,如果不写接口还是一样通知不过来的
9、WebAPI对接优势?WPF和WinForm没区别
C#都可以用,跟框架没关系,就比如HttpClient、SeraiPort、Socket都可以用
和网页比
单体模式
MVC,通过url访问
前后端分离,html请求,webapi,vue
请求下来也是一次通讯
webapi部署同一个服务器数据访问快一些,不同电脑网络延时
中心放一个webapi服务器,多端
学编程多练,踩坑,不能只看
winform也可以数据绑定是加进来的东西,没有wpf整体性更好,学会总结
浙公网安备 33010602011771号