首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在双向绑定组合框(WPF)上调用异步操作

如何在双向绑定组合框(WPF)上调用异步操作
EN

Stack Overflow用户
提问于 2018-01-24 21:32:57
回答 2查看 861关注 0票数 4

当从双向绑定控件(如combobox (wpf数据绑定))中选择一个项时,处理运行异步操作的适当方式是什么?

当我有一个双向绑定属性(例如ComboBox上的SelectedValue )时,我不认为我可以使用Stephen Cleary's NotifyTaskCompletion,因为当用户从下拉列表中选择一个值时,ComboBox本身将需要修改绑定结果属性,这是任务的结果。

我想出的唯一可行的解决方案是在不等待结果的情况下从数据绑定设置器调用异步任务-method。只要async-method触发与ui相关的任何东西的属性更改事件,并且任何异常都会被拾取并相应地传播到ui,就应该没问题,对吧?

我假设这将是异步WPF应用程序中的常见情况。你们是怎么解决这个问题的?

到目前为止我的解决方案是:

<ComboBox 
        ItemsSource="{Binding PossibleItems}"
        DisplayMemberPath="Name"
        SelectedValue="{Binding SelectedItem}"/>

..。

public Item SelectedItem
{
    get { return m_selectedItem; }
    set
    {
        m_selectedItem = value;
        OnPropertyChanged();

        InitializeAsyncAndFirePropertyChanged();   // async Task method not awaited - gives compiler warning CS4014
    }
}

public async Task InitializeAsyncAndFirePropertyChanged(ObservableCollection<RFEnvironment> possibleRfEnvironments)
{
    //should check this method for exceptions and propagate them to the UI via databinding
    OtherDataBoundProperty = await GetSomeStringFromWebAsync(); 
}

public string OtherDataBoundProperty
{
    get { return m_otherDataBoundProperty; }
    set
    {
        m_otherDataBoundProperty = value;
        OnPropertyChanged();
    }
}

注意:我发现了类似的问题,但没有一个涉及控件上的双向绑定,例如组合框。

EN

回答 2

Stack Overflow用户

发布于 2018-01-25 21:35:33

如果您使用的是函数式反应式MVVM框架,如ReactiveUI,则只需观察SelectedItem属性,并在设置该属性时启动所需的任何操作。例如:

this.WhenAnyValue(x => x.SelectedItem)
    .Subscribe(async _ => await InitializeAsyncAndFirePropertyChanged());

属性本身应该启动后台操作,但视图模型可以在设置属性时执行此操作。

有关更多信息,请参阅文档:https://reactiveui.net/docs/concepts/

票数 0
EN

Stack Overflow用户

发布于 2019-05-20 22:31:17

当使用WCF数据绑定时,我在属性设置器中的async调用也有类似的问题。我的解决方案稍微好一点,因为在您的示例中,当InitializeAsyncAndFirePropertyChanged中发生异常时,不会抛出或捕获任何异常。修改后的代码如下。它使用任务继续抛出异常并引发OnPropertyChangedOnPropertyChanged调用可以停留在原来的位置,这取决于您的需求。

public class MyViewModel: INotifyPropertyChanged
{

    private readonly TaskScheduler _uiScheduler;

    public MyViewModel()
    {
        _uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
    }

    public Item SelectedItem
    {
        get { return m_selectedItem; }
        set
        {
            m_selectedItem = value;
            InitializeAsyncAndFirePropertyChanged()
                .ContinueWith(t =>
                {
                    if (t.Exception != null)
                    {
                        throw t.Exception;
                    }

                    OnPropertyChanged();
                }, _uiScheduler);
        }
    }

    public async Task InitializeAsyncAndFirePropertyChanged(ObservableCollection<RFEnvironment> possibleRfEnvironments)
    {
        //should check this method for exceptions and propagate them to the UI via databinding
        OtherDataBoundProperty = await GetSomeStringFromWebAsync();
    }

    public string OtherDataBoundProperty
    {
        get { return m_otherDataBoundProperty; }
        set
        {
            m_otherDataBoundProperty = value;
            OnPropertyChanged();
        }
    }

    .... other code to support INotifyPropertyChanged
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48423750

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档