-
Notifications
You must be signed in to change notification settings - Fork 3
ShellViewModel Class
Bootstrapper.ViewModels.ShellViewModel
When the user runs the bundle, the detect phase starts and the UI is displayed. While the WiX engine runs, the UI should prevent the user from exiting the app or interfering with the action that WiX (or, more importantly, Windows Installer) is performing, except allowing the user to cancel. The easiest way to manage this is to disable everything in the UI except a cancel button while WiX is busy. The shell's view model uses the property IsWaiting
to manage this. This property remains false
until WiX completes the detect phase.
public bool IsWaiting => _model.State.BaStatus == BaStatus.Waiting;
The OnPropertyChanged
method must be called to inform the view when the BA's status changes, so you'll see that implemented in several places in the VM.
This property is true
when a user runs the bundle with the -passive
command line switch. When running passively, I wanted to remove most of the UI controls and only display a progress bar and a cancel button. I'm using BooleanVisibilityConverter to help with this. This converter has a Negate
property that, when set, reverses the normal behavior that the converter provides. You'll see in the ShellView XAML some Grids that wrap other controls and disable or hide them based on VM boolean properties.
<Grid Visibility="{Binding IsPassive, Converter={util:BooleanVisibilityConverter Negate=True}}">
The BA calls this method when WiX's DetectComplete
event is raised. If the BA is running passively, then a follow up action will be sent to let the view model know which action is scheduled.
The first order of business is to inform the view that the BA's status has changed.
OnPropertyChanged(nameof(IsWaiting));
Instead of presenting a series of buttons to the user - install, uninstall, update, repair - and disabling the ones that the user can't use, only the buttons that are valid will be shown. The VM exposes ExecuteCommand
and ExecuteDescription
properties that can be bound to a single button. We determine which action will be assigned to this button by updating these two properties.
if (_model.State.RelatedBundleStatus == BundleStatus.OlderInstalled ||
followupAction == LaunchAction.UpdateReplace ||
followupAction == LaunchAction.UpdateReplaceEmbedded)
{
ExecuteCommand = _updateCommand;
ExecuteDescription = "Update";
}
else if (_model.State.RelatedBundleStatus == BundleStatus.Current ||
followupAction == LaunchAction.Uninstall ||
followupAction == LaunchAction.UnsafeUninstall)
{
ExecuteCommand = _uninstallCommand;
ExecuteDescription = "Uninstall";
}
else
{
ExecuteCommand = _installCommand;
ExecuteDescription = "Install";
}
After that, we determine whether to display the Repair button or not. A method named AssignMessage
is also called. This constructs a message that lets the user know status of the install.
IsRepairAvailable = _model.State.RelatedBundleStatus == BundleStatus.Current;
AssignMessage();
Now that the VM's state has been updated to reflect the model's state, we can refresh all of the VM's commands.
CommandManager.InvalidateRequerySuggested();
Similar to AfterDetect
, this method is called when the install completes. It just resets the progress display and calls AssignMessage
to let the user know how the install went.
ProgressVm.Reset();
AssignMessage();
We also ensure the VM's commands are refreshed.
CommandManager.InvalidateRequerySuggested();
← Previous: ProgressHandler Class || Next: ConfigViewModel Class →