C# 选择更改时MVVM调用异步方法
我有一个简单的列表框,其中所选项目绑定到ViewModel的属性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
<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希望通过交互+动作来实现这一点