Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update textbox from txt file during runtime without clicking "refresh"

Tags:

In wpf, I have a textbox, the content of it coming from a txt file.

in code behine it looks like:

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);
    }
}

The thing is that the txt file content is changing during the runtime, is it possible to be synchronized with those changes? I mean that the textbox content would be change if the txt file is changed. if It's possible please give some code example i c# or XAML.

My solution for now is that I made a "Refresh" button that reads again from the txt file

like image 422
Flufy Avatar asked May 18 '18 18:05

Flufy


2 Answers

You can configure FileSystemWatcher. I added FileWatcherConfigure function as an example.

Whenever file changes, FileChanged event will be published. You should trigger the RefreshTextbox method with that event.

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); });
}
like image 149
Adem Catamak Avatar answered Oct 13 '22 06:10

Adem Catamak


You need a FileSytemWatcher that will trigger an event that you can use to refresh the content of your textbox automatically.

I am using the following in a project I am working on to detect new and updated file.

I watch for the:

  • LastAccess: To get an event when the file has been changed
  • LastWrite: To get an event when the file has been changed
  • FileName: To get an event when a file is renamed that would match

Please note that I am clearing the textbox each time to avoid duplicated lines (your code would append the whole file to the existing content)

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);
    }
  }
}
like image 24
Pic Mickael Avatar answered Oct 13 '22 06:10

Pic Mickael