Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 选择更改时MVVM调用异步方法_C#_Wpf_Mvvm - Fatal编程技术网

C# 选择更改时MVVM调用异步方法

C# 选择更改时MVVM调用异步方法,c#,wpf,mvvm,C#,Wpf,Mvvm,我有一个简单的列表框,其中所选项目绑定到ViewModel的属性 <ListBox SelectedItem="{Binding SelectedItem, Mode=TwoWay}"> 我可以把这个调用放在SelectedItem的setter中,但对我来说这是一种代码味道 public object SelectedItem { get{...} set { foo(); //Compiler warning and blocks UI

我有一个简单的列表框,其中所选项目绑定到ViewModel的属性

<ListBox SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
我可以把这个调用放在SelectedItem的setter中,但对我来说这是一种代码味道

public object SelectedItem
{
    get{...}
    set
    {
         foo(); //Compiler warning and blocks UI
         ...
    }
}
Task.runinside是一个选项,但对我来说仍然很糟糕,foo抛出的异常将被膨胀


代码隐藏SelectionChanged事件可能是另一个选项,但解决此问题的最有效的MVVM方法是什么?

如果您希望采用零代码隐藏的方法,我会这样做

使用交互将SelectedItemChanged事件转换为命令

下面是有关如何将事件转换为命令的代码

   <i:Interaction.Triggers>
        <i:EventTrigger EventName="SomeEvent">
            <i:InvokeCommandAction Command="{Binding Path=SomeCommand, Mode=OneWay}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>

然后,视图模型中的命令将阻塞UI并调用异步功能。

如果您希望采用零代码落后的方法,我将这样做

使用交互将SelectedItemChanged事件转换为命令

下面是有关如何将事件转换为命令的代码

   <i:Interaction.Triggers>
        <i:EventTrigger EventName="SomeEvent">
            <i:InvokeCommandAction Command="{Binding Path=SomeCommand, Mode=OneWay}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>

视图模型中的命令将阻塞UI并调用异步功能。

我将设置一个事件处理程序

差不多

 public class ViewModel:INotifyPropertyChanged
{

    public ViewModel()
    {
        PropertyChanged += SelectedItemChanged;
    }

    private async void SelectedItemChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(SelectedItem))
        {
            await Foo();
        }
    }

    public Task Foo()
    {
        return Task.Run(() =>
        {
            var a = "B";
        });
    }

    private object _selectedItem;

    public object SelectedItem
    {
        get=> _selectedItem;
        set
        {
            if (value != _selectedItem)
            {
                _selectedItem = value;
                OnPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

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

我会设置一个事件处理程序

差不多

 public class ViewModel:INotifyPropertyChanged
{

    public ViewModel()
    {
        PropertyChanged += SelectedItemChanged;
    }

    private async void SelectedItemChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(SelectedItem))
        {
            await Foo();
        }
    }

    public Task Foo()
    {
        return Task.Run(() =>
        {
            var a = "B";
        });
    }

    private object _selectedItem;

    public object SelectedItem
    {
        get=> _selectedItem;
        set
        {
            if (value != _selectedItem)
            {
                _selectedItem = value;
                OnPropertyChanged();
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

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

我会使用一个调用DataContext中异步方法的async SelectedChanged事件处理程序。@Clemens作为一个MVVM puriest,我想尽量减少后面代码的使用。后面的最小代码是Wait ViewModelDataContext.SomeAsyncMethodlistBox.SelectedItem@克莱门斯,让我换个说法。空代码隐藏将是我的最终目标。@Clemens希望通过Interaction+Action实现这一点。我会使用一个async SelectedChanged事件处理程序,在DataContext中调用一个异步方法。@Clemens作为MVVM最纯粹的工具,我希望尽可能减少代码隐藏的使用ViewModelDataContext.SomeAsyncMethodlistBox.SelectedItem@克莱门斯,让我换个说法。我的最终目标是实现空代码。@Clemens希望通过交互+动作来实现这一点