Asynchronous method calls ComboBox selection with MVVM

I have a problem displaying graphs that are filtered when I select ComboBoxwithout blocking the user interface. Statistical filtering is quite heavy and should start async. This works fine until I try to call FilterStatisticsAsyncand MonthSelectionChangedfrom the property setting tool. Does anyone have any good advice on how to solve or get around this?

XAML is as follows:

        <ComboBox x:Name="cmbMonth"
                  ItemsSource="{Binding Months}" 
                  SelectedItem="{Binding SelectedMonth }"
                  IsEditable="True"
                  IsReadOnly="True"

And the set ViewModel property looks like this:

    public string SelectedMonth
    {
        get { return _selectedMonth; }
        set { SetProperty(ref _selectedMonth, value); LoadStatisticsAsync(); MonthSelectionChanged(); }
    }

SetProperty comes from a base class that encapsulates INPC as follows:

        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        protected virtual void SetProperty<T>(ref T member, T value, [CallerMemberName] string propertyName = null)
        {
            if (Equals(member, value))
                return;

            member = value;
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
+4
source share
1 answer

, :

    public class AsyncProperty<T> : INotifyPropertyChanged
    {
        public async Task UpdateAsync(Task<T> updateAction)
        {
            LastException = null;
            IsUpdating = true;

            try
            {
                Value = await updateAction.ConfigureAwait(false);
            }
            catch (Exception e)
            {
                LastException = e;
                Value = default(T);
            }

            IsUpdating = false;
        }

        private T _value;

        public T Value
        {
            get { return _value; }
            set
            {
                if (Equals(value, _value)) return;
                _value = value;
                OnPropertyChanged();
            }
        }

        private bool _isUpdating;

        public bool IsUpdating
        {
            get { return _isUpdating; }
            set
            {
                if (value == _isUpdating) return;
                _isUpdating = value;
                OnPropertyChanged();
            }
        }

        private Exception _lastException;

        public Exception LastException
        {
            get { return _lastException; }
            set
            {
                if (Equals(value, _lastException)) return;
                _lastException = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

 public AsyncProperty<string> SelectedMonth { get; } = new AsyncProperty<string>();

- :

SelectedMonth.UpdateAsync(Task.Run(() => whateveryourbackground work is));

xaml:

SelectedItem="{Binding SelectedMonth.Value }"

, , , . , -, .

+1

Source: https://habr.com/ru/post/1683266/


All Articles