Click here to Skip to main content
15,887,683 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi guys

I have a WPF application the uses the MVVM pattern, I also have a button in my WPF client application that is binded to the ICommand implementation, How do I make the UI responsive when the command is still running?

Below is my code for my MVVM Implementation

C#
private void processLoginRequest()
        {
            UserService usr = new UserService();
            bool validLoginRequest;
            string test = ComputerHashval(this.OperatorPassword, this.OperatorUserID);
            //Work On....
            try
            {
                validLoginRequest = usr.ProcessLoginRequest(this.OperatorUserID, ComputerHashval(this.OperatorPassword, this.OperatorUserID));

                if (validLoginRequest == true)
                {
                    this.MenuVisibility = true;
                    this.DisplayPage = new Uri("/Views/DashboardView/Dashboard.xaml", UriKind.RelativeOrAbsolute);
                    //usr.RegisterOperatorPresence(new CurrentOperator { OperatorUserID = this.OperatorUserID, OperatorStatus = "Online" });
                }
            }
            catch (ApplicationException ex)
            {
                this.ErrPanelVissible = true;
                this.LoginFailedError = ex.Message;
            }

        }


My ICommand Implmentation
C#
public class LoginRequest : ICommand
        {
            public event EventHandler CanExecuteChanged;
            
            private MainWindowViewModel _authenViewModel;

            public LoginRequest(MainWindowViewModel _viewModel)
            {
                this._authenViewModel = _viewModel;
                this._authenViewModel.PropertyChanged += (s, e) =>
                {
                    if (this.CanExecuteChanged != null)
                    {
                        this.CanExecuteChanged(this, new EventArgs());
                    }
                };
            }

            public bool CanExecute(object parameter)
            {
                return this._authenViewModel.OperatorPassword != null;
            }

            public void Execute(object parameter)
            {
                this._authenViewModel.processLoginRequest();
            }
        }


and my XAML Page

HTML
<Button Content="Login" Height="40"                 Name="LogOnBtn" HorizontalAlignment="Right" Margin="0,10,10,5" Width="89" Background="#FFD0D0D0" FontWeight="Bold" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentControl}},               Path=DataContext.ProcLoginRequest, ValidatesOnExceptions=True, NotifyOnValidationError=True}"/>


Thanks
Posted

1 solution

You need to execute the command in a separate thread. The only problem is that the intermediate results of the command execution might need to interact with the UI.

You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900