在C#WinForm中管理错误/状态文本框
我正在编写一个用于管理字幕文件的UI,它提供了对文件的一些操作,并有一个错误/状态文本框(实际上是一个富文本框)。 我希望能够向文本框中添加指示长操作状态的行,因此我执行了以下操作:在C#WinForm中管理错误/状态文本框,c#,winforms,textbox,status,C#,Winforms,Textbox,Status,我正在编写一个用于管理字幕文件的UI,它提供了对文件的一些操作,并有一个错误/状态文本框(实际上是一个富文本框)。 我希望能够向文本框中添加指示长操作状态的行,因此我执行了以下操作: StatusErrors.Text+=“更改开始时间,正在处理字幕文件…\n”; 长时间操作(状态错误); StatusErrors.Text+=“完成\n” 但我看到的唯一文本是操作结束时的“完成”,这是为什么?尝试使用 StatusErrors.AppendText(“错误消息”) 您只能看到“完成”文本,因
StatusErrors.Text+=“更改开始时间,正在处理字幕文件…\n”;
长时间操作(状态错误);
StatusErrors.Text+=“完成\n”代码>
但我看到的唯一文本是操作结束时的“完成”,这是为什么?尝试使用
StatusErrors.AppendText(“错误消息”) 您只能看到“完成”文本,因为您在与长时间运行的方法相同的线程中更新UI,这会导致在操作运行时锁定UI。使用BackgroundWorker
的DoWork
事件执行长时间运行的操作,并更新ProgressChanged
事件中的状态文本。BackgroundWorker
的另一种选择是在每次状态更新后调用Application.DoEvents()
。我的猜测(目前只是猜测)是可能会出现问题,因为您使用“\n”换行。相反,尝试使用以下方法:
StatusErrors.Text = "Log line 1" + Environment.NewLine;
后来
StatusErrors.AppendText("Log line 2" + Environment.NewLine);
一旦你有足够的文本,你会注意到RichTextBox不会自动滚动到文本的末尾,而自动滚动会很麻烦。(如果您执行类似于StatusErrors.Text+=“Blah Blah.”
的操作,每次都会重置您的位置,而.AppendText
我不相信会这样做。)现在,使用WPF很容易,因为有一个ScrollToEnd
函数,但使用常规WinForms可能会更复杂一些。我认为最常用的方法是
StatusErrors.SelectionLength = 0;
StatusErrors.SelectionStart = StatusErrors.Text.Length - 1;
StatusErrors.ScrollToCaret();
我认为这有其问题:例如,它将文本框置于焦点位置。另一种方法是使用Windows API函数实现它
// from http://bitmatic.com/c/implementing-a-scrolling-richtextbox
class ScrollingRichTextBox : System.Windows.Forms.RichTextBox
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(
IntPtr hWnd,
uint Msg,
IntPtr wParam,
IntPtr lParam);
private const int WM_VSCROLL = 277;
private const int SB_LINEUP = 0;
private const int SB_LINEDOWN = 1;
private const int SB_TOP = 6;
private const int SB_BOTTOM = 7;
public void ScrollToBottom()
{
SendMessage(Handle, WM_VSCROLL, new IntPtr(SB_BOTTOM), new IntPtr(0));
}
public void ScrollToTop()
{
SendMessage(Handle, WM_VSCROLL, new IntPtr(SB_TOP), new IntPtr(0));
}
public void ScrollLineDown()
{
SendMessage(Handle, WM_VSCROLL, new IntPtr(SB_LINEDOWN), new IntPtr(0));
}
public void ScrollLineUp()
{
SendMessage(Handle, WM_VSCROLL, new IntPtr(SB_LINEUP), new IntPtr(0));
}
}
此外,如中所述,如果您希望写入日志并在方法中执行同步等待时更新日志,则可能的解决方案是在写入后调用Application.DoEvents()
您需要显示该longOperation
函数的代码。请尝试在窗体上调用Update()(更改后),更改可能会在下次运行时更新。在longOperation()之前调用StatusErrors.Update()可以让您将使用线程的时间推迟一段时间。