Как мне теперь записать время в RichTextBox в приложении WPF? - PullRequest
0 голосов
/ 06 ноября 2019

Вот мои коды, основной файл 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 будет обновлено. Но оно блокируется в то время как() и ничего не печатать в richTextBox.

Как я могу решить это?

Ответы [ 2 ]

2 голосов
/ 06 ноября 2019

Проблема в том, что вы спите в нити диспетчера. Вы намеревались разместить его после вызова диспетчера?

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 отправляет код внутри блока для запуска в потоке пользовательского интерфейса. Помещение в режим сна Приостановляет работу потока пользовательского интерфейса, по существу вызывая его зависание.

ОБНОВЛЕНИЕ: Лучшим решением было бы использование таймера диспетчера.

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();
    }
}
1 голос
/ 06 ноября 2019

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

 if (richTextBox.InvokeRequired)
 {
      richTextBox.Invoke(new MethodInvoker(delegate
      {
          richTextBox.Refresh();

       }));
 }
 else richTextBox.Refresh();
 Application.DoEvents();

Если это не сработает, попробуйте сделать что-то вроде запуска в режиме отладки и проверки значения p в определенные моменты времени, или попробуйте изменить значение textbox.Text напрямуючтобы увидеть, где ваша настоящая ошибка

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