WPF Binding Render Gui Progress

I know that there are several implementations here and there, but I still couldn’t “block” something really useful ...

Whenever I install some DataContext or ItemsSource component on some large object, there is this “frozen GUI rendering” that makes the application really annoying (even when using virtualization).

I know that I can iterate over an object and set elements one by one and show progress, but I am looking for a different approach that can allow me to show some moving indicators while the graphical interface is rendering. I also prefer to have some progress bar and not just change the mouse pointer.

Is there a decent way to achieve the following results?

Many thanks

+3
source share
3 answers

The Zamboni example is very good, but does not solve the problem of a frozen GUI .

As already mentioned, there is currently no easy way to have something “live” for updating the gui control while the GUI is busy rendering.

Currently, I have discovered some kind of event that is "alive and kicking" , and gui is rendering, althogh should be turned off when it is not needed, since it can run something like 60 times per second.

CompositionTarget.Rendering += ReportRenderProgress;

ReportRenderProgress(), , , . , WPF , .

+3

. GUI ( ). Windows ( , / ), .

. GUI, DoEvents() / + , .

, - .

+2

BackgroundWorker contains everything you need.

EDIT

In WPF, Dispatcher is automatically used to call end-to-end method calls. Check out Create more responsive Dispatcher applications in the MSDN log.

I also compiled some code snippets from ViewModel in which BackgroundWorker updates the progress bar.

<ProgressBar 
    VerticalContentAlignment="Stretch" VerticalAlignment="Stretch"
    HorizontalAlignment="Stretch"
    Minimum="0" Maximum="100"
    Value="{Binding Path=BarPosition, Mode=TwoWay}"/>


// configure the background worker...
_backgroundWorker = new BackgroundWorker();
_backgroundWorker.WorkerReportsProgress = true;
_backgroundWorker.WorkerSupportsCancellation = true;
_backgroundWorker.DoWork += new DoWorkEventHandler(_backgroundWorker_DoWork);
_backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_backgroundWorker_RunWorkerCompleted);
_backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(_backgroundWorker_ProgressChanged);

// control progress bar position
private int _barPosition = 0;
public int BarPosition
{
   get { return _barPosition; }
   set
   {
      _barPosition = value;
      OnPropertyChanged("BarPosition");
   }
}

// long operation
void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
  BackgroundWorker bw = sender as BackgroundWorker;
  if (bw != null)
  {
     int pos;

     for (int i = 0; i < 100; ++i
     {
        // report progress here for our long running operation..
        pos = i/100;
        bw.ReportProgress(pos);
        Thread.Sleep(1000);            // fake long operation
     }
  }
}

// report progress,,,
void _backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
   BackgroundWorker bw = sender as BackgroundWorker;
   if (bw != null)
   {
      BarPosition = e.ProgressPercentage;
   }
}

// reset scroll bar position
void _backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
   BackgroundWorker bw = sender as BackgroundWorker;
   if (bw != null)
   {
     BarPosition = 0;

     // Forcing the CommandManager to raise the RequerySuggested event to refresh UI...
     CommandManager.InvalidateRequerySuggested();
   }
}
+2
source

Source: https://habr.com/ru/post/1782548/


All Articles