WPF UI question with/without MvvM
Posted: Wed Mar 09, 2022 8:36 pm
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
in the XAML
In my general method I have this code:
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?
Dick
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 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;
});
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