首页 > 其他分享 >WPF中使用委托机制更新UI内容

WPF中使用委托机制更新UI内容

时间:2022-12-30 12:14:40浏览次数:37  
标签:委托 Windows System private 线程 UI using WPF

在开发WPF应用程序时,UI线程不做高负载的工作,需要交给其他工作者线程去干。当工作者线程干完活得到一个结果后需要发送给UI线程进行展示,那最好的方法就是使用委托机制了。如果你不信邪,偏要在工作者线程里面调用控件去直接更新,这除了说明你对UI绘制的流程不了解之外,还说明你很固执。不仅仅是WPF这样,安卓也是这么一个机制。

下面代码展示了如何适用委托机制来实现UI的更新。

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading;
 6 using System.Threading.Tasks;
 7 using System.Windows;
 8 using System.Windows.Controls;
 9 using System.Windows.Data;
10 using System.Windows.Documents;
11 using System.Windows.Input;
12 using System.Windows.Interop;
13 using System.Windows.Media;
14 using System.Windows.Media.Imaging;
15 using System.Windows.Navigation;
16 using System.Windows.Shapes;
17 
18 namespace DlgtTest
19 {
20     /// <summary>
21     /// Interaction logic for MainWindow.xaml
22     /// </summary>
23     public partial class MainWindow : Window
24     {
25         // 声明委托类型,相当于C语言里面typedef一个函数指针类型
26         private delegate void UIUpdaterCallback(string what);
27         // 定义一个委托对象,它还没有被实例化
28         private UIUpdaterCallback mUpdateCallback;
29 
30         private uint mButtonClickedCount = 0;
31 
32         public MainWindow()
33         {
34             InitializeComponent();
35             CtrlTextBox.Clear();
36 
37             // 将推脱对象实例化,实例化的构造函数传入的就是实际要被执行的函数
38             mUpdateCallback = new UIUpdaterCallback(UIUpdaterEntry);
39 
40             // 创建并启动一个线程,它里面发消息给UI线程做更新
41             Thread t = new Thread(new ThreadStart(ThreadEntry));
42             // 一定要设置 IsBackground 为 true,除非这个线程能够自动退出
43             t.IsBackground = true;
44             t.Start();
45         }
46 
47         private void UIUpdaterEntry(string what)
48         {
49             if (null == what)
50             {
51                 CtrlTextBox.AppendText("空字符串消息\n");
52                 return;
53             }
54             CtrlTextBox.AppendText(what);
55             CtrlTextBox.ScrollToEnd();
56         }
57 
58         private void CtrlButton_Click(object sender, RoutedEventArgs e)
59         {
60             mButtonClickedCount++;
61             string msg = "我作为一个按键已经被第 " + mButtonClickedCount + " 按下了。\n";
62             this.Dispatcher.Invoke(mUpdateCallback, new object[] { msg });
63         }
64 
65         private void ThreadEntry()
66         {
67             string msg;
68             uint count = 0;
69 
70             while(true)
71             {
72                 Thread.Sleep(1000);
73                 count++;
74                 msg = "我作为一个线程已经休眠 " + count + " 秒了。\n";
75                 this.Dispatcher.Invoke(mUpdateCallback, new object[] { msg });
76             }
77         }
78     }
79 }
主窗口类
 1 <Window x:Class="DlgtTest.MainWindow"
 2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 6         xmlns:local="clr-namespace:DlgtTest"
 7         mc:Ignorable="d"
 8         Title="MainWindow" Height="450" Width="800">
 9     <Grid>
10         <Grid.RowDefinitions>
11             <RowDefinition Height="4*"></RowDefinition>
12             <RowDefinition Height="*"></RowDefinition>
13         </Grid.RowDefinitions>
14         <TextBox x:Name="CtrlTextBox" Grid.Row="0" Margin="5,5,5,5" VerticalScrollBarVisibility="Visible"></TextBox>
15         <Button x:Name="CtrlButton" Grid.Row="1" Margin="5,5,5,5" Click="CtrlButton_Click">Test</Button>
16     </Grid>
17 </Window>
窗口布局XML

程序运行截图

 

  

需要注意的是创建的新线程如果要随着窗口关闭时自动结束,那就必须要设置“IsBackground”为真,否则你把窗口关闭了,后台的线程还是在执行的,你在系统的任务管理器里面可以看到这个窗口对应的进程还在跑着。

 

标签:委托,Windows,System,private,线程,UI,using,WPF
From: https://www.cnblogs.com/ssdq/p/17014555.html

相关文章