-
Notifications
You must be signed in to change notification settings - Fork 2
ViewModel Base
The ViewModelBase
inherts from ThreadSaveViewModelActor, the base class for all ViewModel components of WPFToolsAwesome. The ThreadSaveViewModelActor
can enqueue actions into an set dispatcher and can also track what Dispatcher
to use. This is very important in an multi Dispatcher
process. The ThreadSaveViewModelActor
main functions are the ViewModelAction(Action action, DispatcherPriority priority = DispatcherPriority.DataBind)
and BeginViewModelAction(Action action, DispatcherPriority priority = DispatcherPriority.DataBind)
. Both take care of the state of the Dispatcher
and will also prevent oversubscription.
Oversubscription. When an operation enqueues another operation while the subscribing operation is already executing inside the
Dispatcher
Thread. This uses far more resources as necessary as the operation can be executed directly within the callers context instead of bothering the Dispatcher
Also all actions enqueued via Begin/ViewModelAction are all enqueued into the Dispatcher
as DataBind priority. This helps keeping your WPF application responsible.
This class should be one of the two base classes every ViewModel should inhert. It contains the Implementation of INotifyPropertyChanged
& INotifyPropertyChanging
. Directly implemented are they as SendPropertyChanged(string|Expression)
and SendPropertyChanging(string|Expression)
and both are using the CallerMemberNameAttribute
. There are extensions that functions as alias for these methods that cover most variants of those names like RaisePropertyChanged
, OnPropertyChanged
, FirePropertyChanged
.
ViewModelBase
also contains an ChangeTracking mechanism that is covered by the IAcceptPendingChange interface. To use this Interface you must use the SetProperty method to set your properties.
Example:
ctor()
{
PendingChange += OnPendingChange;
}
private void OnPendingChange(object sender, AcceptPendingChangeEventArgs e)
{
e.CancelPendingChange = true | false; //setting this to true will stop the update
e.NewValue //readonly
e.OldValue //readonly
e.PropertyName //readonly
}
private string _text;
public string Text
{
get { return _text; }
set { SetProperty(ref _text, value); }//SetProperty will raise the PendingChange event
}
Then you can attach yourself to the PendingChange event of that given ViewModelBase
and use the CancelPendingChange
property of that event arg to cancel the property setting operation. The same event arg contains also the new value and the property name.
Sometimes you want to make a lot of changes in bulk to a ViewModel
. In that case its better to turn of the event handling of the INotifyPropertyChanged
event and resume it later. This is implemented directly into the ViewModelBase
by using the DeferNotification
and ResumeNotification
methods.
Example:
private string _text;
public string Text
{
get { return _text; }
set { SetProperty(ref _text, value); }//SetProperty will raise the INotifyPropertyChanged.PropertyChanged event
}
public void DoStuff()
{
Text = "Hello World"; //this will set the property and immediately raise the PropertyChanged event
using (DeferNotification())
{
Text = "H";//all this calls will set the property but will not raise the event
Text = "E";
Text = "L";
Text = "L";
Text = "O";
Text = " World";
}//only when the scope is disposed all gathered property names will be raised
}