WPF UI question with/without MvvM

This forum is meant for questions and discussions about the X# language and tools
Post Reply
ic2
Posts: 1798
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

WPF UI question with/without MvvM

Post by ic2 »

Although this is not an X# question, the program is actually C#, some of you may be able to comment on this.

I finalized a backup program (now using DotNetZip). During collecting the files, adding them to the zip and saving the zip file, the program issues progress information in 3 different WPF TextBlocks. I centralized the actual assignment in a method. Also there are some status updates in between.

Originally I had a mix of MvvM and directly assigning a value to a control using it's name. I decided to use MvvM all over, checked all the "bells & whistles" like get/set/RaisePropertyChanged("Name") and public partial class MainWindow : Window, INotifyPropertyChanged. Plus

Code: Select all

TextBlock x:Name="ProgressText" Text="{Binding Progress, UpdateSourceTrigger=PropertyChanged}"
in the XAML

In my general method I have this code:

Code: Select all

public void ShowMessage(string cMessage,string cCtrl,bool lUpdateUI)

this.Dispatcher.Invoke(() =>
{
//ProgressText.Text=cMessage;
Progress=cMessage;
});
This means I can easily switch between assigning the message to the defined property or directly to the control using the assigned x:name, by moving the comment //. The Dispatcher.Invoke prevents issues with directly assigning to the control when I call the methods from a timer, which is a different thread.

Now what happens is that some of the messages are not updated in the UI (while I do not see the difference, processs wise). That comes expected, and by calling ExtensionMethods.ProcessUITasks(), a not recommended (why not?) but great working C# equivalent of VO's ApplicationExecWhileEvent I can fix this.

But my question is: updating also does not work on more or less the same places when I use MvvM. And I can also fix that with ProcessUITasks!

I thought that one of the advantages of MvvM would be that Windows takes care of UI updating. But it works more or less the same as directly updating the TextBlock and it needs a forced UI update just as much.

Not sure what advantages remain using MvvM except some academic, like separating program logic and UI, which has no value in a program like this. Or do I miss something?

Code: Select all

		public static void ProcessUITasks()
			// From http://stackoverflow.com/questions/8128670/force-redraw-before-long-running-operations
			// When called, forces the UI to redraw. It is however not recommended
			{
				DispatcherFrame frame = new DispatcherFrame();
				Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(delegate (object parameter)
				{
					frame.Continue = false;
					return null;
				}), null);
				Dispatcher.PushFrame(frame);
			}// ProcessUITasks

Dick
User avatar
wriedmann
Posts: 3644
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

WPF UI question with/without MvvM

Post by wriedmann »

Hi Dick,
to have an UI updated, you have to use threads.
I'm using the BackgroundWorker class for this purpose:

Code: Select all

virtual public method Berechnen( oObject as object ) as void
if _oWorker == null
	_oWorker := BackgroundWorker{}
	_oWorker:WorkerReportsProgress := true
	_oWorker:WorkerSupportsCancellation := true
	_oWorker:DoWork += ExecuteProcessAsync
	_oWorker:ProgressChanged += ProgressProcessAsync
	_oWorker:RunWorkerCompleted += CompletedProcessAsync
	_oWorker:RunWorkerAsync()
endif
return
and then

Code: Select all

method ExecuteProcessAsync( oSender as object, e as DoWorkEventArgs ) as void
local oProcess as KalenderBerechnenProcess

self:IsExecuting := true
oProcess := KalenderBerechnenProcess{ _oWorker }
oProcess:ExceptionHandler	:= self:ProcessException
if ( lSuccess := oProcess:Initialize( _dVonDatum, _dBisDatum, _lOverwrite, _lAllgemeiner ) )
		lSuccess				:= oProcess:Process()
endif
oProcess:CleanUp()
self:IsExecuting := false

return
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
ic2
Posts: 1798
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

WPF UI question with/without MvvM

Post by ic2 »

Hello Wolfgang,

The Stackoverflow post where I got my ProcessUITasks from refers to the backgroundworker as well as a better alternative, so you code sample is very useful..

Your reply confirms for me that MvvM (with many lines of extra code) doesn't serve a useful purpose. To be sure I ran a few speed tests for the same backup set and this is the remarkable conclusion:

MvvM with ProcessUITasks 1:26
MvvM without ProcessUITasks 1:02

Non MvvM with ProcessUITasks 1:04
Non MvvM without ProcessUITasks 1:00

Conclusion is that using MvvM is always slower than directly writing in controls, even a a lot slower with ProcessUITasks while with non MvvM the differene is much smaller (4 instead of 26 seconds), while not having the (only) advantage I thought it had (that it would handle updating the UI without "tricks").

In the meantime, using ProcessUITasks the GUI still isn't locked up (I can press a Stop button on which I get quick reaction) so I will keep the Backgroundworker in mind for future projects but in general I can conclude that what is supposed to be the recommended programming technique MvvM is the slowest while it is not updating the UI anyway and the not recommended technique is the fastest without any noticeable drawback.

So much for "recommended techniques".

Dick
User avatar
wriedmann
Posts: 3644
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

WPF UI question with/without MvvM

Post by wriedmann »

Hi Dick,
I'm not using WPF because of speed - I'm perfectly conscious that WPF is slower than Windows Forms or Console mode programs.
I'm using WPF because it permits a GUI that has unparalleled functionalitiies, and works flawlessy from small to large monitors.
When it comes to small helper and testing applications I use Windows Forms applications because they are much faster to build and I don't need to separate between GUI and processing thread.
For longer processing normally I delegate the work to background Windows services that are running on separate machines - either the file or a processing server. That makes it also easier for the user if he does not have to wait.
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
ic2
Posts: 1798
Joined: Sun Feb 28, 2016 11:30 pm
Location: Holland

WPF UI question with/without MvvM

Post by ic2 »

Hello Wolfgang,

I think your arguments for WPF/Winforms are exactly right. I decided years ago when I began .Net programming, to use WPF as this appeared to be the future of programming and Winforms wasn't. But I am gradually using Winforms more often; WPF misses quite some features and Microsoft doesn't do much with WPF anymore; I think they have one old aged programmer left who is allowed to keep working on it until he is retired.

in this backup program I have a treeview with checkboxes which represent the files/directories to be included in the zip, and I couldn't get it set/read in WPF, not with databinding and not directly. When I created a Winforms window for it I could get it all working, setting and reading the values (and colours) directly.

Hence it's a good thing we can easily mix both.

If you like to see the result, here's the help file which I also put on my site. The first full screen is the Winform window and the next 2 are WPF. https://www.ic2.com/IC2Backup/IC2BackupEN.html.

Dick
Post Reply