WPF 应用程序启动后,会有两个线程:
1. 一个是用来处理UI呈现(处理UI的请求,比如输入和展现等操作)。
2. 一个用来管理 UI的 (对UI元素及整个UI进行管理)。
像Winform一样,WPF在线程里面是不可以直接操作UI元素,如果在一个非UI线程里操作UI元素,将会报错!
XAML代码如下:
1 <Window x:Class="WpfApp1112.Window1" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="Window1" Height="300" Width="300"> 5 <Grid> 6 <TextBlock Height="23" Name="textBlock1" Text="window1" VerticalAlignment="Top" Width="176" /> 7 <Button x:Name="btnOk" Content="Click" Width="88" Height="22" Click="btnOk_Click"/> 8 </Grid> 9 </Window>
后台代码如下:
那么我们可以用Window.Dispatcher.Invoke() 来操作。代码如下:
1 /// <summary> 2 /// Button的单击事件 3 /// </summary> 4 /// <param name="sender"></param> 5 /// <param name="e"></param> 6 private void btnOk_Click(object sender, RoutedEventArgs e) 7 { 8 Thread thread = new Thread(showContent); 9 thread.Start(); 10 } 11 private void showContent() 12 { 13 Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate() 14 { 15 Thread.Sleep(TimeSpan.FromSeconds(10)); 16 this.textBlock1.Text = "明天周五了!"; 17 }); 18 }
今天最大的收获是在学习WPF线程操作UI元素的时候发现了一个惊喜,呵呵,解释不清,直接代码,原来方法可以这么写,以下代码实现效果和上面完全一样
1 private void btnOk_Click(object sender, RoutedEventArgs e) 2 { 3 //第一种方法: 4 new Thread(() => 5 { 6 Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => 7 { 8 Thread.Sleep(TimeSpan.FromSeconds(10)); 9 this.textBlock1.Text = "明天周五了!"; 10 })); 11 }).Start(); 12 13 //第二种方法: 14 new Thread(() => 15 { 16 Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)delegate() 17 { 18 Thread.Sleep(TimeSpan.FromSeconds(10)); 19 this.textBlock1.Text = "明天周五了!"; 20 }); 21 }).Start(); 22 }
比起上面的代码好简洁啊,经过测试以上两个方法都可以实现异步调用,但是第二个方法比较好理解,第一个方法以后慢慢理解!