C#WPF/XAML从任意位置访问文本框/任意线程帮助
我正在尝试从程序中的任何位置向文本框发帖,不管它在哪个线程中,或者是哪个对象拥有它等等 我试过下面的几件事,都不行 尝试1:tbLog在清理中不存在,另一个线程拥有它C#WPF/XAML从任意位置访问文本框/任意线程帮助,c#,wpf,textbox,backgroundworker,C#,Wpf,Textbox,Backgroundworker,我正在尝试从程序中的任何位置向文本框发帖,不管它在哪个线程中,或者是哪个对象拥有它等等 我试过下面的几件事,都不行 尝试1:tbLog在清理中不存在,另一个线程拥有它 namespace MyProgram { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Cleanin
namespace MyProgram
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Cleaning clng = new Cleaning();
}
public buttonStartTasks_Click(object sender, RoutedEventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
Dispatcher.Invoke(new Action(delegate { tbLog.Text += "Starting to clean"; }));
clng.cleanRoom();
}
worker.RunWorkerAsync();
}
}
}
namespace Tasks
{
public class Cleaning
{
public void cleanRoom()
{
tbLog.Text += "Dusting....";
Thread.Sleep(50000); //work sim
tbLog.Text += "Sweeping....";
Thread.Sleep(50000); //work sim
tbLog.Text += "Hanging up clothes....";
Thread.Sleep(50000); //work sim
tbLog.Text += "Organize shelves....";
Thread.Sleep(50000); //work sim
tbLog.Text += "Remaining odds and ends....";
Thread.Sleep(50000); //work sim
}
}
}
尝试2:我尝试将tbLog传递到清理中。我得到了这个错误“调用线程无法访问这个对象,因为另一个线程拥有它”。这是有道理的
namespace MyProgram
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Cleaning clng = new Cleaning(tbLog);
}
public buttonStartTasks_Click(object sender, RoutedEventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
Dispatcher.Invoke(new Action(delegate { tbLog.Text += "!!! Starting to clean !!!"; }));
clng.cleanRoom();
}
worker.RunWorkerAsync();
}
}
}
namespace Tasks
{
public class Cleaning
{
private TextBox LOG { get; set; }
public Cleaning(TextBox log)
{
this.LOG = log;
}
public void cleanRoom()
{
LOG.Text += "Dusting....";
Thread.Sleep(50000); //work sim
LOG.Text += "Sweeping....";
Thread.Sleep(50000); //work sim
LOG.Text += "Hanging up clothes....";
Thread.Sleep(50000); //work sim
LOG.Text += "Organize shelves....";
Thread.Sleep(50000); //work sim
LOG.Text += "Remaining odds and ends....";
Thread.Sleep(50000); //work sim
}
}
}
尝试3:我试图在清理中使用Dispatcher,但出现编译错误,告诉我它不存在。所以现在我被卡住了。我不知道还能尝试什么。我在谷歌上搜索了很多,但总是归结为线程所有权错误
if (Dispatcher.Thread != Thread.CurrentThread)
{
Dispatcher.Invoke(new Action(delegate { this.LOG.Text += "No clean for you!"; }));
}
else
{
this.LOG.Text += "No clean for you!";
}
所有人的文本框:
<TextBox Name="tbLog"
Height="200"
Width="200"
HorizontalAlignment="Left"
VerticalAlignment="Top"
VerticalScrollBarVisibility="Visible"
IsReadOnly="True" />
谢谢你的帮助 这是因为您不能仅对来自主UI线程以外的其他线程的控件执行操作。如果要执行此操作,必须使用
调度程序中的Invoke
或BeginInvoke
可以找到这方面的介绍,您还可以找到代码示例,这些示例将帮助您解决此问题。我认为最好的方法是将textbox的文本属性绑定到依赖项属性,并从backgroundworker更新依赖项属性。要从线程更新文本框的值,您需要实现INotifyPropertyChanged。我昨天刚刚在尝试从另一个线程增量加载列表框时遇到了这个问题。我将Dispatcher.Invoke()更改为Application.Current.Dispatcher.Invoke()。您需要。如果您想知道:使用System.Windows.Application,而不是System.Windows.Forms.Application