Обновите текстовое поле из txt файла во время выполнения, не нажимая кнопку «обновить» - PullRequest
0 голосов
/ 18 мая 2018

В wpf у меня есть текстовое поле, содержимое которого приходит из txt-файла.

в коде вот так:

public MyWindow()
{
    InitializeComponent();
    ReadFromTxt();
}
void Refresh(object sender, RoutedEventArgs e)
{
    ReadFromTxt();
}

void ReadFromTxt()
{
    string[] lines = System.IO.File.ReadAllLines(@"D:\Log.txt");
    foreach (string line in lines)
    {
        MyTextBox.AppendText(line + Environment.NewLine);
    }
}

Дело в том, что txt-файлсодержимое меняется во время выполнения, возможно ли синхронизироваться с этими изменениями?Я имею в виду, что содержимое текстового поля будет изменено, если текстовый файл изменяется.если возможно, приведите пример кода ic # или XAML.

Мое решение на данный момент состоит в том, что я сделал кнопку «Обновить», которая снова читает из текстового файла

Ответы [ 4 ]

0 голосов
/ 18 мая 2018

Просто, чтобы уточнить другие ответы, FileSystemWatcher может быть вариантом, но вы должны определенно рассмотреть опрос в качестве альтернативы.Для удобочитаемости (основанной на мнении) и надежности (см. Эту ветку ).Обратите внимание, что есть много других сообщений, в которых подчеркиваются проблемы, связанные с использованием FileSystemWatcher.

. Под опросом я имею в виду поиск изменений в определенные периодические периоды.Можно было бы использовать Таймер , искать изменения и действовать соответственно.

0 голосов
/ 18 мая 2018

Вы можете настроить FileSystemWatcher.В качестве примера я добавил функцию FileWatcherConfigure.

При каждом изменении файла будет опубликовано событие FileChanged.Вы должны запустить метод RefreshTextbox с этим событием.

FileSystemWatcher fileWatcher = new FileSystemWatcher();
string filePath = @"./Log.txt";
public MainWindow()
{
    InitializeComponent();

    ReadFromTxt();
    FileWatherConfigure();
}

public void FileWatherConfigure()
{
    fileWatcher.Path = System.IO.Path.GetDirectoryName(filePath);
    fileWatcher.Filter = System.IO.Path.GetFileName(filePath);
    fileWatcher.Changed += FileWatcher_Changed;
    fileWatcher.EnableRaisingEvents = true;
}

private void FileWatcher_Changed(object sender, FileSystemEventArgs e)
{
    Thread.Sleep(TimeSpan.FromSeconds(1));

    ReadFromTxt();
}


void ReadFromTxt()
{
    string[] lines = System.IO.File.ReadAllLines(filePath);
    MyTextBox.Dispatcher.Invoke(() => { this.MyTextBox.Text = string.Join(Environment.NewLine, lines); });
}
0 голосов
/ 18 мая 2018

Вам необходим FileSytemWatcher, который будет запускать событие, которое вы можете использовать для автоматического обновления содержимого вашего текстового поля.

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

Я наблюдаю за:

  • LastAccess: для получения события, когда файл был изменен
  • LastWrite: для получения события, когда файл был изменен
  • FileName: чтобы получить событие при переименовании файла, которое будет соответствовать

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

public class MyWindow : Window
{
  public MyWindow()
  {
    InitializeComponent();

    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = @"D:\";
    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName;
    watcher.Filter = "Log.txt";

    // Add event handlers.
    watcher.Changed += new FileSystemEventHandler(OnFileChanged);
    watcher.Created += new FileSystemEventHandler(OnFileChanged);
    watcher.Renamed += new RenamedEventHandler(OnFileRenamed);

    // Begin watching.
    watcher.EnableRaisingEvents = true;

    ReadFromTxt();
  }

  private void OnFileChanged(object source, FileSystemEventArgs e)
  {
    ReadFromTxt();
  }

  private void OnFileRenamed(object source, RenamedEventArgs e)
  {
    ReadFromTxt();
  }

  private void ReadFromTxt()
  {
    // The easiest way is to just replace the whole text
    MyTextBox.Text = "";
    if (System.IO.File.Exists(@"D:\Log.txt") == false)
    {
      return;
    }
    string[] lines = System.IO.File.ReadAllLines(@"D:\Log.txt");
    foreach (string line in lines)
    {
      MyTextBox.AppendText(line + Environment.NewLine);
    }
  }
}
0 голосов
/ 18 мая 2018

Вид:

<TextBox Text="{Binding myText}"/>

Модель:

private string _myText;
public string MyText{
    get { return _myText; }
    set { _myText = value;
          NotifyPropertyChanged();
}

Реализация INotifyPropertyChanged в вашем окне И изменение свойства MyText, а не MyTextBox

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