I have a problem to refresh my UI in a wpf / mvvm project.
When I log out there is a action on UI to display "waiting" object and then do a long process.
All codes I present are not complete
private void btnPower_Click(object sender, RoutedEventArgs e)
{
// IHM changes
btnRightMenuShow.IsEnabled = false;
btnRightMenuShow.Visibility = Visibility.Hidden;
StationWindowViewModel stnWindowVM = (StationWindowViewModel)DataContext;
stnWindowVM.ProgressMode = LoadingProcessViewModel.ProgressMode.Sending;
// PRocess
if (stnWindowVM.PowerOffCmd.CanExecute(null))
{
stnWindowVM.PowerOffCmd.Execute(null);
}
}
Like this the ihm is like frozen during the process and never refresh() before the application ended.
I first try to use a background worker like
private void btnPower_Click(object sender, RoutedEventArgs e)
{
// IHM changes
btnRightMenuShow.IsEnabled = false;
btnRightMenuShow.Visibility = Visibility.Hidden;
StationWindowViewModel stnWindowVM = (StationWindowViewModel)DataContext;
stnWindowVM.ProgressMode = LoadingProcessViewModel.ProgressMode.Sending;
// PRocess
powerOffWorker.RunWorkerAsync(stnWindowVM);
}
private void powerOffWorker_DoWork(object Sender, System.ComponentModel.DoWorkEventArgs e)
{
if (stnWindowVM.PowerOffCmd.CanExecute(null))
{
stnWindowVM.PowerOffCmd.Execute(null);
}
}
In this case the IHM is refreshed but i have threading errors with some code trying to access object created by parent thread on main process (The calling thread cannot access this object because a different thread owns it)
So i try to use a Dispatcher like
private void btnPower_Click(object sender, RoutedEventArgs e)
{
// IHM changes
btnRightMenuShow.IsEnabled = false;
btnRightMenuShow.Visibility = Visibility.Hidden;
StationWindowViewModel stnWindowVM = (StationWindowViewModel)DataContext;
stnWindowVM.ProgressMode = LoadingProcessViewModel.ProgressMode.Sending;
// PRocess
this.Dispatcher.Invoke(new Action(() =>
{
if (stnWindowVM.PowerOffCmd.CanExecute(null))
{
stnWindowVM.PowerOffCmd.Execute(null);
}
}));
}
I also try dispatcher inside backgrounworker but with those dispatcher i don't have anymore problem with calling thread but the UI is not updating.
EDIT
This is my test for async/await implementation
private void btnPower_Click(object sender, RoutedEventArgs e)
{
// IHM changes
btnRightMenuShow.IsEnabled = false;
btnRightMenuShow.Visibility = Visibility.Hidden;
StationWindowViewModel stnWindowVM = (StationWindowViewModel)DataContext;
stnWindowVM.ProgressMode = LoadingProcessViewModel.ProgressMode.Sending;
// PRocess
PowerOffAsync(stnWindowVM);
}
private async void PowerOffAsync(StationWindowViewModel stnWindowVM)
{
await Task.Run(() =>
{
if (stnWindowVM.PowerOffCmd.CanExecute(null))
{
stnWindowVM.PowerOffCmd.Execute(null);
}
});
}
In the PowerOffCmd process ther is some operation on object like list which gives error with calling thread...