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整体性更好,学会总结

 

posted on 2025-03-21 11:46  张彦山  阅读(34)  评论(0)    收藏  举报