如何在 WPF 应用程序的 RichTextBox 中记录时间?
Posted
技术标签:
【中文标题】如何在 WPF 应用程序的 RichTextBox 中记录时间?【英文标题】:How can I record time now in RichTextBox in WPF application? 【发布时间】:2020-03-02 11:16:00 【问题描述】:这是我的代码,主要的 xaml.cs 文件:
//using statements...
namespace WpfAppTestRichTextBox
public partial class MainWindow : Window
public Paragraph p = new Paragraph();
public MainWindow()
InitializeComponent();
Start();
// Initialize the richTextBox...
public void Start()
Run r = new Run("");
p.Inlines.Add(r);
richTextBox.Document.Blocks.Add(p);
// Button Click and Start a new Thread to record time for each second.
private void Button_Click(object sender, RoutedEventArgs e)
System.Threading.Thread th = new System.Threading.Thread(ChangeText);
th.Start();
public void ChangeText()
while(true)
this.Dispatcher.Invoke(new Action(() =>
string time = System.DateTime.Now.ToString() + "\n";
Run r = new Run(time);
p.Inlines.Add(r);
System.Threading.Thread.Sleep(1000);
));
我将新的 Run() 添加到 Paragraph 并期望richTextBox 的内容将被刷新。但它在 while() 中阻塞并且在richTextBox 中什么也不打印。
我该如何解决这个问题?
【问题讨论】:
【参考方案1】:问题是您在调度程序线程中处于睡眠状态。您是否打算在调度程序调用之后放置它?
while(true)
this.Dispatcher.Invoke(new Action(() =>
string time = System.DateTime.Now.ToString() + "\n";
Run r = new Run(time);
p.Inlines.Add(r);
));
System.Threading.Thread.Sleep(1000);
Thread.Sleep
在指定的时间内暂停当前线程。
Dispatcher.Invoke 调度块内的代码以在 UI 线程上运行。将睡眠放在那里会挂起 UI 线程,本质上会导致它冻结。
更新:更好的解决方案是使用调度程序计时器。
public partial class MainWindow : Window
private DispatcherTimer _timer = new DispatcherTimer();
public Paragraph p = new Paragraph();
public MainWindow()
InitializeComponent();
_timer.Interval = new TimeSpan(0, 0, 1);
_timer.Tick += _timer_Tick;
private void _timer_Tick(object sender, EventArgs e)
string time = System.DateTime.Now.ToString() + "\n";
Run r = new Run(time);
p.Inlines.Add(r);
private void Button_Click(object sender, RoutedEventArgs e)
Run r = new Run("");
p.Inlines.Add(r);
richTextBox.Document.Blocks.Add(p);
_timer.Start();
【讨论】:
它对我有用!但我认为它只是休眠 1000 毫秒。为什么 Sleep() 语句会阻塞 UI 线程? 我在回答中添加了更多细节。【参考方案2】:首先,将您的方法更改为异步是一个好主意,但要回答您的问题,您的 UI 可能只是由于方法永无止境或将控制权交还给调用者而没有刷新。尝试强制刷新:
if (richTextBox.InvokeRequired)
richTextBox.Invoke(new MethodInvoker(delegate
richTextBox.Refresh();
));
else richTextBox.Refresh();
Application.DoEvents();
如果这不起作用,请尝试在调试模式下运行并在特定时间检查 p 的值,或者尝试直接更改 textbox.Text 的值以查看您的实际错误在哪里
【讨论】:
以上是关于如何在 WPF 应用程序的 RichTextBox 中记录时间?的主要内容,如果未能解决你的问题,请参考以下文章
WPF RichTextBox 如何滚动到光标所在位置滚动条操作