Лучший подход к выводу скользящего журнала Windows Forms в TextBox - PullRequest
30 голосов
/ 21 декабря 2008

В приложении Forms я отображаю вывод журнала из долго работающего приложения командной строки, которое генерировало много выходных данных. Я запускаю программу в фоновом режиме, фиксирую ее вывод и в настоящее время отображаю ее в TextBox, используя AppendText. Я предпочитаю отображать только последние 1000 строк. Удаление строк из TextBox обходится дорого, а TextBox не очень подходит для просмотра скользящих журналов.

Есть какие-нибудь идеи о том, как лучше всего управлять окном журналирования в Windows Forms?

Ответы [ 5 ]

15 голосов
/ 21 декабря 2008

Раньше списки делали подобные вещи. Вы просто удаляете первую строку, если количество строк достигает, скажем, 1000. Если строка журнала слишком длинная, вы можете сделать список немного шире (зависит от информации журнала и от того, возможно ли уловить значение из первого видимого слова без горизонтальной прокрутки) и сделать горизонтальную полосу прокрутки видимой.

11 голосов
/ 21 декабря 2008

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

    delegate void UpdateCCNetWindowDelegate(String msg);

     private void Message2CCNetOutput(String message)
     {
         // Check whether the caller must call an invoke method when making method calls to listBoxCCNetOutput because the caller is 
         // on a different thread than the one the listBoxCCNetOutput control was created on.
         if (listBoxCCNetOutput.InvokeRequired)
         {
             UpdateCCNetWindowDelegate update = new UpdateCCNetWindowDelegate(Message2CCNetOutput);
             listBoxCCNetOutput.Invoke(update, message);
         }
         else
         {
             listBoxCCNetOutput.Items.Add(message);
             if (listBoxCCNetOutput.Items.Count > Program.MaxCCNetOutputLines)
             {
                 listBoxCCNetOutput.Items.RemoveAt(0); // remove first line
             }
             // Make sure the last item is made visible
             listBoxCCNetOutput.SelectedIndex = listBoxCCNetOutput.Items.Count - 1;
             listBoxCCNetOutput.ClearSelected();
         }
     }
7 голосов
/ 20 сентября 2009

Имел такую ​​же потребность и очень ценил эту помощь. Это слегка измененная версия.

Создать список:

<ListBox x:Name="lbLog" Background="LightGray"></ListBox>

В главном потоке (в начальной части кода) поместите это, чтобы сохранить ссылку на поток пользовательского интерфейса:

Thread m_UIThread;
....
m_UIThread = Thread.CurrentThread;

Тогда это ваш метод журнала, вызываемый из любого потока:

public void AddToLog(String message)    
{
    if (Thread.CurrentThread != m_UIThread)
    {
        // Need for invoke if called from a different thread
        this.Dispatcher.BeginInvoke(
            DispatcherPriority.Normal, (ThreadStart)delegate()
            {
                AddToLog(message);
            });
    }
    else
    {
        // add this line at the top of the log
        lbLog.Items.Insert(0, message);

        // keep only a few lines in the log
        while (lbLog.Items.Count > LOG_MAX_LINES)
        {
            lbLog.Items.RemoveAt(lbLog.Items.Count-1);
        }
    }
}
2 голосов
/ 19 января 2012

очень простое решение

Textbox1.Appendtext(<yourtext>)

для катящегося бревна типа консоли

2 голосов
/ 21 декабря 2008

Мне нужно было сделать это некоторое время назад, и Listbox был решением. Никто даже не заметит разницу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...