Управление ошибками / текстовым полем состояния в C # WinForm - PullRequest
0 голосов
/ 21 августа 2011

Я пишу пользовательский интерфейс для управления файлами субтитров, он предлагает некоторые операции над файлом и имеет текстовое поле ошибок / статуса (которое на самом деле является форматированным текстовым полем).Я хочу иметь возможность добавлять строки в текстовое поле, которые указывают на состояние длинной операции, поэтому я сделал следующее:

StatusErrors.Text += "Changing time tarted, subtitle file is being processed...\n"; longOperation(StatusErrors); StatusErrors.Text += "Done\n";

Но я вижу только один текст "Готово "в конце операции, почему это так?

Ответы [ 3 ]

2 голосов
/ 21 августа 2011

Вы видите только текст «Готово», потому что вы обновляете пользовательский интерфейс в том же потоке, что и ваш долгосрочный метод, в результате чего пользовательский интерфейс блокируется во время выполнения операции. Используйте событие BackgroundWorker DoWork для выполнения длительной операции и обновления текста состояния в событии ProgressChanged. Альтернативой BackgroundWorker будет вызов Application.DoEvents() после каждого обновления статуса.

0 голосов
/ 21 августа 2011

Я предполагаю (на данный момент только предположение), что могут быть проблемы, потому что вы используете '\ 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();

У этого есть свои проблемы, я думаю: он помещает TextBox в фокус, например.Альтернативой может быть что-то вроде решение в этой статье , которое реализует его с помощью функций 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() после записи.

0 голосов
/ 21 августа 2011

Попробуйте использовать StatusErrors.AppendText («Сообщение об ошибке»);

...