很多小伙伴对“跨线程或跨类”使用WPF或WinFrom页面的控件不太明白,奉上一段小案例供参考(下面为WPF代码,WinFrom同理):
注:在WPF或WinFrom中,UI元素只能由其主线程来操作,其他任何线程都不可以直接操作UI,可以使用Dispatcher.Invoke(同步操作)或Dispatcher.BeginInvoke (异步操作)来操作。
1.xaml页面代码:
1 <Window 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:WpfPaging" 7 xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol" x:Class="WpfPaging.测试跨线程跨类调用控件" 8 mc:Ignorable="d" 9 Title="MainWindow" Height="700" Width="1000" Loaded="Window_Loaded"> 10 <Grid> 11 <DataGrid HorizontalAlignment="Left" Height="623" Margin="10,10,0,0" VerticalAlignment="Top" Width="972" Name="dgtext" CanUserAddRows="True" AutoGenerateColumns="True"> 12 <DataGrid.Columns> 13 <DataGridTextColumn Header="选中" Width="35" /> 14 <DataGridTextColumn Header="公司名称" Width="80" Binding="{Binding 公司名称, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 15 <DataGridTextColumn Header="姓名" Width="80" Binding="{Binding 姓名, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 16 <DataGridTextColumn Header="年龄" Width="80" Binding="{Binding 年龄, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 17 <DataGridTextColumn Header="职务" Width="80" Binding="{Binding 职务, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 18 </DataGrid.Columns> 19 </DataGrid> 20 <Button Content="添加" HorizontalAlignment="Left" Margin="10,638,0,0" VerticalAlignment="Top" Width="75" Name="btnAdd" Click="BtnAdd_Click" RenderTransformOrigin="1.68,0.545"/> 21 <Button Content="保存" HorizontalAlignment="Left" Margin="121,638,0,0" VerticalAlignment="Top" Width="75" Name="btnSave" Click="btnSave_Click" RenderTransformOrigin="1.68,0.545"/> 22 <Button Content="删除" HorizontalAlignment="Left" Margin="236,638,0,0" VerticalAlignment="Top" Width="75" x:Name="btnDele" Click="btnDele_Click" RenderTransformOrigin="1.68,0.545"/> 23 <Button Content="跨线程调用控件" HorizontalAlignment="Left" Margin="334,638,0,0" VerticalAlignment="Top" Width="113" x:Name="btn1" Click="btn1_Click" RenderTransformOrigin="1.68,0.545"/> 24 <Button Content="跨类调用控件" HorizontalAlignment="Left" Margin="458,638,0,0" VerticalAlignment="Top" Width="97" x:Name="btn2" Click="btn2_Click" RenderTransformOrigin="1.68,0.545"/> 25 <Button Content="跨线程跨类调用控件" HorizontalAlignment="Left" Margin="566,638,0,0" VerticalAlignment="Top" Width="140" x:Name="btn3" Click="btn3_Click" RenderTransformOrigin="1.68,0.545"/> 26 </Grid> 27 </Window>
xaml.cs代码
1 using System.Collections.Generic; 2 using System.Threading; 3 using System.Windows; 4 using System.Windows.Threading; 5 using WpfPaging.NewFolder1; 6 7 namespace WpfPaging 8 { 9 // 声明一个委托 10 //public delegate void ChangeForm1TextBoxValue(string txt); 11 /// <summary> 12 /// MainWindow.xaml 的交互逻辑 13 /// </summary> 14 public partial class 测试跨线程跨类调用控件 : Window 15 { 16 #region 变量 17 // 委托事件 18 //public static event ChangeForm1TextBoxValue ChangeTextBoxValue; 19 #endregion 20 21 public 测试跨线程跨类调用控件() 22 { 23 InitializeComponent(); 24 } 25 26 private void Window_Loaded(object sender, RoutedEventArgs e) 27 { 28 // 获取这些新添加的记录 29 List<Information> lstInformati = new List<Information>(); 30 Information information = new Information(); 31 information.公司名称 = "公司名称0"; 32 information.姓名 = "姓名0"; 33 information.年龄 = "年龄0"; 34 information.职务 = "职务0"; 35 lstInformati.Add(information); 36 dgtext.ItemsSource = lstInformati; 37 dgtext.Items.Refresh(); 38 } 39 // 跨线程调用控件 40 private void btn1_Click(object sender, RoutedEventArgs e) 41 { 42 Thread t1 = new Thread(() => 43 { 44 // 获取这些新添加的记录 45 List<Information> lstInformati = new List<Information>(); 46 Information information = new Information(); 47 information.公司名称 = "公司名称跨线程"; 48 information.姓名 = "姓名跨线程"; 49 information.年龄 = "年龄跨线程"; 50 information.职务 = "职务跨线程"; 51 lstInformati.Add(information); 52 Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate 53 { 54 dgtext.ItemsSource = lstInformati; 55 dgtext.Items.Refresh(); 56 }); 57 }) 58 { 59 IsBackground = true 60 }; 61 t1.Start(); 62 } 63 // 跨类调用控件 64 private void btn2_Click(object sender, RoutedEventArgs e) 65 { 66 TreadTest1 treadTest1 = new TreadTest1(); 67 treadTest1.TestC(this.dgtext); 68 } 69 // 跨线程跨类调用控件 70 private void btn3_Click(object sender, RoutedEventArgs e) 71 { 72 Thread t1 = new Thread(TestITC); 73 t1.Start(); 74 } 75 76 private void TestITC() 77 { 78 TreadTest1 treadTest1 = new TreadTest1(); 79 treadTest1.TestITC( this.dgtext); 80 } 81 } 82 }
调用类代码:
1 using System.Collections.Generic; 2 using System.Windows.Threading; 3 using System.Windows.Controls; 4 using System.Threading; 5 6 namespace WpfPaging.NewFolder1 7 { 8 //// 声明一个委托 9 //public delegate void ChangeForm1TextBoxValue(string txt); 10 public class TreadTest1 11 { 12 //// 委托事件 13 //public event ChangeForm1TextBoxValue ChangeTextBoxValue; 14 /// <summary> 15 /// 跨类调用控件 16 /// </summary> 17 internal void TestC(System.Windows.Controls.DataGrid dgtext) 18 { 19 // 获取这些新添加的记录 20 List<Information> lstInformati = new List<Information>(); 21 Information information = new Information(); 22 information.公司名称 = "公司名称 跨类"; 23 information.姓名 = "姓名 跨类"; 24 information.年龄 = "年龄 跨类"; 25 information.职务 = "职务 跨类"; 26 lstInformati.Add(information); 27 dgtext.ItemsSource = lstInformati; 28 dgtext.Items.Refresh(); 29 } 30 /// <summary> 31 /// 跨线程跨类调用控件 32 /// </summary> 33 /// <param name="dgtext"></param> 34 internal void TestITC(DataGrid dgtext) 35 { 36 // 获取这些新添加的记录 37 List<Information> lstInformati = new List<Information>(); 38 Information information = new Information(); 39 information.公司名称 = "跨线程跨类调用控件"; 40 information.姓名 = "跨线程跨类调用控件"; 41 information.年龄 = "跨线程跨类调用控件"; 42 information.职务 = "跨线程跨类调用控件"; 43 lstInformati.Add(information); 44 dgtext.Dispatcher.Invoke(DispatcherPriority.Normal, (ThreadStart)delegate 45 { 46 dgtext.ItemsSource = lstInformati; 47 dgtext.Items.Refresh(); 48 }); 49 } 50 } 51 }