加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 使用MVVM调用ComboBox时的异步方法

发布时间:2020-12-15 22:46:32 所属栏目:百科 来源:网络整理
导读:我在显示通过ComboBox选择过滤的图形而没有UI锁定时遇到问题.统计过滤非常繁重,需要运行异步.这一切都很好,直到我尝试从Property setter调用FilterStatisticsAsync和MonthSelectionChanged.有没有人对如何解决或解决这个问题有一个很好的建议? XAML看起来像
我在显示通过ComboBox选择过滤的图形而没有UI锁定时遇到问题.统计过滤非常繁重,需要运行异步.这一切都很好,直到我尝试从Property setter调用FilterStatisticsAsync和MonthSelectionChanged.有没有人对如何解决或解决这个问题有一个很好的建议?

XAML看起来像这样:

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

而ViewModel属性设置器如下:

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

SetProperty派生自一个封装INPC的基类,如下所示:

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));
        }

解决方法

我会这样做:

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 }"

请注意,属性应反映当前状态,而不是触发可能花费无限时间的进程.因此,需要以不同的方式更新属性,而不仅仅是分配它.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读