简体   繁体   中英

Loading asynchronously in a UserControl WPF with MVVM pattern

I have a small problem async loader in a view with WPF MVVM pattern . I wish that when I click the button Read from UserControl View , send a Command to view model , and then it was off a loading before making execute and it disappeared when I return data . The data is read by a machine via optical USB . All works , the program runs perfectly, just can not bring up the loading so async . The loading is displayed along with the return of reading , because synchronous . How can I do asynchronous ? I tried it with the task but it seems he does not consider the code .

class  ReadAndPrintFromDevice : ICommand
    {
        async Task<int> showLoader()
        {
           model.ShowLoader = true;                         
           return 1;
        }

        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {                    
            return true;
        }

        public async void Execute(object parameter)
        {
            showLoader async here
            //other code..
            showloader async shadow here, after other code
        }
    }

if you need more information tell in the comments that I add all .

I would suggest something like this:

public class ReadAndPrintFromDeviceAsyncCommand : PropertyChangedBase, ICommand
{
    private bool _IsBusy;

    public bool IsBusy
    {
        get { return _IsBusy; }
        private set
        {
            _IsBusy = value;
            NotifyOfPropertyChange();
        }
    }

    public bool CanExecute(object parameter)
    {
        return !IsBusy;
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public async void Execute(object parameter)
    {
        IsBusy = true;

        await ...

        IsBusy = false;
    }
}

By using an IsBusy property, you can simply set that to be true before executing the asynchronous operation, and once it's done, set it back to false.

You can then bind your control to the IsBusy property:

<MyControl Visibility="{Binding SomeCommand.IsBusy, ...}"

The above example would require a BooleanToVisibilityConverter to work, but I think you get the idea.

Also, the command uses a PropertyChangedBase which I have created to simply make implementing INotifyPropertyChanged a bit easier, the code for this class is here:

public abstract class PropertyChangedBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyOfPropertyChange([CallerMemberName]string propertyName = null)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM