当目前任何班级更改文本时,我目前仍然坚持如何更新文本框的文本。目前,只有我的主线程这样做,并且我尝试了各种方法(包括调度)来从任何地方更新视图。我的代码如下所示:
XAML:
<TextBox x:Name ="textBoxResults" Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}"/>
XAML.CS:
public partial class MainWindow : Window
{
public ConsoleLog cl { get; set; }
public MainWindow()
{
InitializeComponent();
MainWindow_Load();
cl = new ConsoleLog();
DataContext = cl;
}
}
private void ButtonBeginTests_Click(object sender, RoutedEventArgs e)
{
new Thread(() =>
{
App.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, new Action(() =>{
tc = new TestController(.., .., cl); //other args not important
tc.beginTest();
}));
}).Start();
}
ConsoleLog类:
using System;
using System.ComponentModel;
namespace Test_DesktopApplication.src
{
public class ConsoleLog : INotifyPropertyChanged
{
private string text;
public string Text
{
get { return text; }
set
{
text = value;
OnPropertyChanged("Text");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public void addToLog(string text)
{
App.Current.Dispatcher.Invoke(new Action(delegate { this.Text += text; }));
}
}
一个类在后台进程的单独线程中多次调用“addToLog”。我可能做错什么的任何迹象?
编辑:我可以实际上通过在每次addToLog调用之后使用它来使其工作:
App.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, new ThreadStart(delegate { }));
然而,我不知道这是否是一个“好”的修复。
编辑2:
我已更新MainWindow类以显示何时调用此类,调用日志的类如下:
public class Testcontroller
{
ConsoleLog cl;
public GEN2TestController(.., .., ConsoleLog console)
{
//other constructor things
cl = console;
}
public void beginTest(){
testList[0].result = unprogrammedCurrent_test(.., ..); //this is an example of what the test looks like..
cl.addToLog(TestList[0].result);
...//repeat for the rest of the test lists and tests..
...
...
}
在完成所有测试之前,日志不会更新。
答案 0 :(得分:1)
你的代码示例工作正常!
编辑:应该没有必要像这样强制一个空的调度程序循环,这相当于旧的WinForms Application.DoEvents()你的代码中必须有其他东西阻塞在调度程序(UI线程)中,您可能应该分享一个如何构造和启动后台工作程序的示例。
我在表单中添加了一个按钮:
<Button Margin="0,267,376,0" Click="Button_Click" Height="54" VerticalAlignment="Top" HorizontalAlignment="Right" Width="142"/>
按钮点击后面代码中的逻辑:
private void Button_Click(object sender, RoutedEventArgs e)
{
cl.addToLog(DateTime.Now.ToString() + Environment.NewLine);
}
我怀疑你发出的是你如何调用addToLog()很可能你正在调用一个不同的对象实例来设置为数据上下文。
我已修改您的示例以包含从表单启动的后台工作程序,这非常有效:
public partial class MainWindow : Window
{
private void Button_Click(object sender, RoutedEventArgs e)
{
if (worker.IsBusy)
worker.CancelAsync();
else
{
cl.Text = String.Empty;
worker.RunWorkerAsync();
}
}
public ConsoleLog cl { get; set; }
private BackgroundWorker worker = null;
public MainWindow()
{
InitializeComponent();
cl = new ConsoleLog();
DataContext = cl;
worker = new BackgroundWorker { WorkerSupportsCancellation = true };
worker.DoWork += Worker_DoWork;
worker.RunWorkerCompleted += (object sender, RunWorkerCompletedEventArgs e) => cl.addToLog($"{e.Result}");
}
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
Random r = new Random();
while(true)
{
if ((sender as BackgroundWorker).CancellationPending) break;
cl.addToLog(DateTime.Now.ToString() + Environment.NewLine);
System.Threading.Thread.Sleep(r.Next(500, 3000));
}
e.Result = "Stop" + Environment.NewLine;
}
}