gpt4 book ai didi

c# - 如何从后台工作线程更改 XAML 元素?

转载 作者:行者123 更新时间:2023-12-03 12:51:00 25 4
gpt4 key购买 nike

在下面的代码示例中,我想 改变颜色文本框的前景文本 来自我的后台线程 ,但它得到 错误 :

This thread cannot access this object since it is in another thread.



我必须在下面的代码中进行哪些更改,以便后台工作线程可以更改 TextBox 中的前景色?

回答:

谢谢安迪,这只是一个小小的疏忽,为了后代,这里是更正的代码:
using System.Windows;
using System.ComponentModel;
using System.Threading;
using System.Windows.Media;

namespace TestBackgroundWorker7338
{
public partial class Window1 : Window
{
private BackgroundWorker _worker;
int _percentageFinished = 0;

public Window1()
{
InitializeComponent();
ButtonCancel.IsEnabled = false;
}

private void Button_Start(object sender, RoutedEventArgs e)
{
_worker = new BackgroundWorker();
_worker.WorkerReportsProgress = true;
_worker.WorkerSupportsCancellation = true;

_worker.DoWork += (s, args) =>
{
BackgroundWorker worker = s as BackgroundWorker;
int numberOfTasks = 300;
for (int i = 1; i <= numberOfTasks; i++)
{
if (worker.CancellationPending)
{
args.Cancel = true;
return;
}

Thread.Sleep(10);
float percentageDone = (i / (float)numberOfTasks) * 100f;
worker.ReportProgress((int)percentageDone);
}
};

_worker.ProgressChanged += (s,args) =>
{
_percentageFinished = args.ProgressPercentage;
ProgressBar.Value = _percentageFinished;
Message.Text = _percentageFinished + "% finished";
if (_percentageFinished < 500)
{
Message.Text = "stopped at " + _percentageFinished + "%";
}
else
{
Message.Text = "finished";
}

if (_percentageFinished >= 70)
{
InputBox.Foreground = new SolidColorBrush(Colors.Red);
}
else if (_percentageFinished >= 40)
{
InputBox.Foreground = new SolidColorBrush(Colors.Orange);
}
else if (_percentageFinished >= 10)
{
InputBox.Foreground = new SolidColorBrush(Colors.Brown);
}
else
{
InputBox.Foreground = new SolidColorBrush(Colors.Black);
}

};

_worker.RunWorkerCompleted += (s,args) =>
{
ButtonStart.IsEnabled = true;
ButtonCancel.IsEnabled = false;
ProgressBar.Value = 0;
};

_worker.RunWorkerAsync();
ButtonStart.IsEnabled = false;
ButtonCancel.IsEnabled = true;

}

private void Button_Cancel(object sender, RoutedEventArgs e)
{
_worker.CancelAsync();
}
}
}

最佳答案

正如 Andy 所说,控件的属性更改必须发生在 UI 线程上。

WPF 提供了一个 Dispatcher类,可以更轻松地将控件调用路由到适当的 UI 线程。 WPF 中的控件公开了 Dispatcher属性对象将调用分派(dispatch)到适当的 UI 线程。

您可以按如下方式使用它(我将在 worker.ReportProgress((int)percentageDone); 方法中的 Button_Start 行之后添加它):

// the Window class exposes a Dispatcher property, alternatively you could use
// InputBox.Dispatcher to the same effect
if (!Dispatcher.CheckAccess())
{
Dispatcher.Invoke(new Action(() => ChangeForegroundColor(percentageDone));
}
else
{
ChangeForegroundColor(percentageDone);
}

...
private void ChangeForegroundColor(int percentageDone)
{
if (percentageDone >= 90)
{
InputBox.Foreground = new SolidColorBrush(Colors.Red);
}
else if(percentageDone >=10)
{
InputBox.Foreground = new SolidColorBrush(Colors.Orange);
}
}

关于c# - 如何从后台工作线程更改 XAML 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1206077/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com