wpf(怎么跨线程访问wpf控件)

在编写代码时,我们经常会碰到一些子线程中处理完的信息,需要通知另一个线程(我这边处理完了,该你了)。

但是当我们通知WPF的UI线程时需要用到Dispatcher。

首先我们需要想好在UI控件上需要显示什么内容。然后写一个显示UI内容的方法。

以下是代码

 private void UIThreaddosomething(string s)    //UI线程要做的事情
       {
            //do something  //这里也可以做一些其他的事情
            Label2.Content = s;
            ellipse1.Fill=new SolidColorBrush(Colors.Red);
            ellipse2.Fill=new SolidColorBrush(Colors.Red);
        }

然后我们声明一个委托,由于UIThreaddosomething有一个字符串参数,所以声明的委托要与其保持一致

public delegate void RefleshUI(string s);

然后在创建一个方法,这个方法将通过委托将子线程与UI线程联系起来。

        private void delegatedosomething(string s)
        {
            ellipse1.Dispatcher.Invoke(new RefleshUI(UIThreaddosomething), s);
          //  ellipse2.Dispatcher.Invoke(new RefleshUI(UIThreaddosomething), s);
        }

这里我之前以为只要UI控件里有多少控件,就需要在此方法里用多少个Dispatcher,最后发现是我太年轻,只需要一个控件用上Dispatcher就好啦。

这里我们就可以跨线程访问WPF的UI控件了

完整代码如下,(这里我们也还可以使用一个中间方法来调用了UI方法,这样当程序有多个UI方法时,我们可以在这个中间方法中做一些处理,然后决定引用那些UI方法)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;

namespace 子线程通知主线程做一些事情
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        public delegate void RefleshUI(string s);
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Thread th;
            th = new Thread(fun);
            th.IsBackground = true;
            th.Start();
        }

        private void fun(object obj)
        {

            //////做一些子线程该做的事情
            /////
            /////
            /**子线程完成后通知UI线程*/
            delegatedosomething("你好,我是jjp_god,我做完了");
        }
        private void delegatedosomething(string s)
        {
            ellipse1.Dispatcher.Invoke(new RefleshUI(dofun), s);
          //  ellipse2.Dispatcher.Invoke(new RefleshUI(UIThreaddosomething), s);
        }
        private void UIThreaddosomething(string s)    //UI线程要做的事情
        {
            //do something  //这里也可以做一些其他的事情
            tb_show.Text = s;
            Label2.Content = s;
            ellipse1.Fill=new SolidColorBrush(Colors.Red);
            ellipse2.Fill=new SolidColorBrush(Colors.Red);
        }
        private void dofun(string s)
        {
            UIThreaddosomething(s);
        }

    }}

原文地址:https://www.cnblogs.com/jianjipan/p/10476265.html

时间: 2024-07-31 22:51:14

wpf(怎么跨线程访问wpf控件)的相关文章

跨线程访问UI控件时的Lambda表达式

工作中经常会用到跨线程访问UI控件的情况,由于.net本身机制,是不允许在非UI线程访问UI控件的,实际上跨线程访问UI控件还是 将访问UI的操作交给UI线程来处理的, 利用Control.Invoke方法,将操作传递给UI线程,不推荐使用CheckForIllegalCrossThreadCalls = false; Control.Invoke的签名 // // 摘要: // 在拥有此控件的基础窗口句柄的线程上执行指定的委托. // // 参数: // method: // 包含要在控件的线

理解SynchronizationContext,如何在Winform里面跨线程访问UI控件

SynchronizationContext 类是一个基类,可提供不带同步的自由线程上下文. 此类实现的同步模型的目的是使公共语言运行库内部的异步/同步操作能够针对不同的异步模型采取正确的行为.此模型还简化了托管应用程序为在不同的同步环境下正常工作而必须遵循的一些要求.同步模型的提供程序可以扩展此类并为这些方法提供自己的实现.(来自MSDN)简而言之就是允许一个线程和另外一个线程进行通讯,SynchronizationContext在通讯中充当传输者的角色.另外这里有个地方需要清楚的,不是每个线

C# Winform 跨线程更新UI控件常用方法总结(转)

出处:http://www.tuicool.com/articles/FNzURb 概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件的线程访问它”的异常.处理跨线程更新Winform UI控件常用的方法有4种: 1. 通过UI线程的SynchronizationContext的Post/Send方法更新: 2. 通过UI控件的Invoke/BegainInvoke方法更新: 3. 通过BackgroundWorker取代Thre

C# 跨线程调用form控件技巧及byte[]与string型相互转换

跨线程调用form控件技巧 private delegate void MethodSocket(object obj);//使用托管 ss = "OK"; this.BeginInvoke(new MethodSocket(InvokerReadMsg), ss);//this指向本窗体,回调函数InvokerReadMsg, private void InvokerReadMsg(object obj)//在这个函数里面可以直接访问Form控件<span style=&quo

C# Winform 跨线程更新UI控件常用方法汇总

C# Winform 跨线程更新UI控件常用方法汇总 概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效: 从不是创建控件的线程访问它”的异常.处理跨线程更新Winform UI控件常用的方法有4种:1. 通过UI线程的SynchronizationContext的Post/Send方法更新:2. 通过UI控件的Invoke/BeginInvoke方法更新: 3. 通过BackgroundWorker取代Thread执行异步操作:4. 通过设置窗体

Winform中子线程访问界面控件时被阻塞解决方案

public partial class WebData_Import : Form { //声明用于访问主界面的委托类型 public delegate void deleGetOrderdata(string info); //声明访问主界面委托类型的变量 public deleGetOrderdata OptGetOrderData; int CompanyID = 0; public WebData_Import() { InitializeComponent(); cmbCompany

(转).NET 4.5中使用Task.Run和Parallel.For()实现的C# Winform多线程任务及跨线程更新UI控件综合实例

http://2sharings.com/2014/net-4-5-task-run-parallel-for-winform-cross-multiple-threads-update-ui-demo 在C# WINFORM的开发中,难免会遇到多线程的开发以提高程序的执行效率.自己刚才开始在做多线程的开发时也遇到了很多这方面的问题,比如:如何使用并实现多线程功能.跨线程更新UI控件等问题.还记得最初使用的是System.Threading命名空间下的Thread类来实现的: C# 1 2 3

扩展BindingList,防止增加、删除项时自动更新界面而不出现“跨线程操作界面控件 corss thread operation”异常

在做界面程序时,常常需要一些数据类,界面元素通过绑定等方式显示出数据,然而由于UI线程不是线程安全的,一般都需要通过Invoke等方式来调用界面控件.但对于数据绑定bindingList而言,没法响应listchang事件,导致后端的grid等控件不能更新数据.废了好大的劲终于找到一个UIBindingList,实现线程数据的同步! using System; using System.ComponentModel; using System.Threading; using System.Wi

C# winform 跨线程更改窗体控件的属性

当winform程序中新开一个线程,是无法改变主线程中窗体控件的属性的,否则运行时会报错. 若想在其他线程中控制主线程中的窗体控件,则必须利用BeginInvoke方法. 例如:添加一个名为textbox1的TextBox控件,想将它的Visible设置为false,则执行下面的代码即可 textbox1.BeginInvoke(new Action(() => { textbox1.Visible= false; })); 另外WPF中,想达到winform同样的效果,利用Dispatcher