I'm making a chessboard, I want to see progress while it's done. Chessboard is not classical, it contains millions of fields, the process of creation itself takes time. Sometimes the creation process takes up to 2 minutes. I want to visually see when the process itself will be over. It does not have to be a progress bar, it can be any control that will not slow down the process itself.
When I use Progress.Dispatcher.Invoke (()
... I actually slow down the creation process and it takes 5 times longer than usual. When I use BackgroundWorker
and ReportProgress
... I also slow down the creation process and it takes 5 to 8 times more than usual.
I just want to show the user progress by using any control or class that will not slow down the process. Some idea?
Rectangle[,] square = new Rectangle[x, x];
for (int row = 0; row < x; row++)
for (int col = 0; col < x; col++)
{
square[row, col] = new Rectangle()
{
Height = squareSize,
Width = squareSize
};
Grid.SetColumn(square[row, col], col);
Grid.SetRow(square[row, col], row);
if ((row + col) % 2 == 0)
{
square[row, col].Fill = new SolidColorBrush(System.Windows.Media.Color.FromRgb(233, 223, 191));
}
else
{
square[row, col].Fill = new SolidColorBrush(System.Windows.Media.Color.FromRgb(112, 42, 44));
}
LayoutRoot.Children.Add(square[row, col]);
// Watch process of creation in real time
if (cbCreationProcess.IsChecked == true)
Progress.Dispatcher.Invoke(() => Progress.Value = x, DispatcherPriority.Background);
}
This solution has worked for me in the past.
ProgressWindowControl.xaml
ProgressWindowControl.cs
A helper class to open the window:
A service so you can use Dependency Injection (I didn't include the interface, just create one as needed):
And finally in your ViewModel (assuming you have injected the service):
You can also pass a window to the Show method and then the window will be attached to it and input will be blocked while the progress window is shown, if no window is provided, the progress bar is shown on top of any other window (TopMost=true):
You could also use a messenger to trigger the progress window.
EDIT
Removed DevExpress dependency.
obviously any addition of functionality is going to slow it down as you're well aware.
what I would do if I was told to use the above code is likely create a timer and poke into where-ever you have your current
row
andcol
increments and its up to you what you do with your calculation.All you would have to do is handle the Timer.Elapsed event (whatever kind of timer) and calculate/report current progress in percent or such.
Otherwise, you could write up a separate thread and run it in a loop that sleeps N-milloseconds until drawing is complete—essentially tandem with the idea of using a timer. Generally, this is what we would do to report progress on a playing mp3 or some such object manipulated on a separate thread.
there is a lot of room for you to be creative here and milk some wisdom out of this scenario to optimize results but before considering such...
bare in mind that WPF is a beast when it comes to how it deals with drawing things since it relies heavily on the video hardware, memory, etc... I tend to think of WPF as like html for OpenGL or DirectX. I hope your GPU has a good connection to the heat-sync and doesn't get too hot and/or that you're not working on a laptop with an embedded GPU. I'm being aggressive here, but only because I've blown pleanty of hardware over the years writing software in the write/compile/run/and-repeat cycle. I'd have gotten much more life out of lots of hardware if I played a bit safer. not to mention recent years are getting harder and harder on our hardware.
for the sake of being as creative as possible here
System.Threading.Thread(ThreadStart)
will enable you to set process-priority to a higher value than standard defaults — as opposed to usingBackgroundWorker
or some other such... but I haven't quite wrapped my mind around an implementation with such as this.List<>
and render at the end of a row, column or perhaps every N incremenetx*x
boxes in the end, so if we're explicit about the size, there is so much room for creativity here. I hadn't tinkered with WPF in a while, but this would be a good case for studying and looking at different ways to lay such a thing out (eg: CustomLayoutPanel tut). If you're stuck on the notion of a Grid, there is only so much you can do---I would instinctively be working with Drawing methods for doing this, and would likely come up with a way to draw only what is visible on the screen as needed... or