来自CommunityToolkit.Mvvm的ObservableObject具有允许异步绑定到Task<T> (https://github.com/MicrosoftDocs/CommunityToolkit/blob/main/docs/mvvm/ObservableObject.md#handling-taskt-properties的API) 问题是示例中不包含XAML部件,我不知道绑定应该是什么样子. 谁能给我展示一下下面的例子:

public partial class MainWindowViewModel : ObservableObject
    {
        [RelayCommand]
        private void RequestValue()
        {
            RequestTask = LoadAsync();
        }

        private TaskNotifier<int>? requestTask;

        public Task<int>? RequestTask
        {
            get => requestTask;
            private set => SetPropertyAndNotifyOnCompletion(ref requestTask, value);
        }

        private static async Task<int> LoadAsync()
        {
            await Task.Delay(3000);
            return 5;
        }
<Window>
    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>
    <StackPanel>
        <Button Command="{Binding RequestValueCommand}" Content="Get my value"/>
        <StackPanel Orientation="Horizontal" >
            <TextBlock Text="My value is:"/>
            <TextBlock Text="{Binding ?????????}"/>
        </StackPanel>
    </StackPanel>
</Window>

我希望在按钮被点击后,它等待3秒,然后我的值被更改为5.

我已经判断了他们的示例应用程序,但只绑定到Task,没有绑定到Task<T&>(https://github.com/CommunityToolkit/MVVM-Samples/blob/master/samples/MvvmSampleUwp/Views/ObservableObjectPage.xaml)

推荐答案

你必须等Task号.你的例子不是与Task的结果绑定,而是与Task.Status的结果绑定.为了绑定到结果,你必须await Task对象.

为此,您可以定义一个异步命令:

[RelayCommand]
private async Task RequestValueAsync()
{
  RequestTask = await LoadAsync();
}

private int requestTask;
public int RequestTask
{
  get => requestTask;
  private set => SetProperty(ref requestTask, value);
}

private async Task<int> LoadAsync()
{
  await Task.Delay(3000);
  return 5;
}
<Window>
    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>
    <StackPanel>
        <Button Command="{Binding RequestValueCommand}" Content="Get my value"/>
        <StackPanel Orientation="Horizontal" >
            <TextBlock Text="My value is:"/>
            <TextBlock Text="{Binding RequestTask}"/>
        </StackPanel>
    </StackPanel>
</Window>

If for what reason ever you insist in using TaskNotifier to bind to "async" properties (an asynchronous property is an oxymoron) you simply bind to the property as usual. The TaskNotifier will unwrap the result.
Because asynchronous code implies to be longrunning you should also set Binding.IsAsync to true on the particular Binding:

<Window>
    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>
    <StackPanel>
        <Button Command="{Binding RequestValueCommand}" Content="Get my value"/>
        <StackPanel Orientation="Horizontal" >
            <TextBlock Text="My value is:"/>
            <TextBlock Text="{Binding RequestTask.Result, IsAsync=True}"/>
        </StackPanel>
    </StackPanel>
</Window>

Csharp相关问答推荐

使用源生成器,如何使用所有转换后的 node 的聚合生成源?

有没有一种方法可以将模拟实现委托给实际的类,而不必设置每个方法?

EF Core的GbContent如何 suppress 所有CS 8618(不可为空属性)警告?

如果没有中间变量,可空引用类型将无法工作

MongoDB实体框架核心:表达必须可写

ASP.NET Core 8.0 JWT验证问题:尽管令牌有效,但SecurityTokenNoExpirationError异常

如何在C#中将对象[*,*]直接转换为字符串[*,*]?

AsNoTrackingWithIdentitySolutions()似乎不起作用?

(乌龙)1&#比c#中的UL&#慢吗?

如何定义EFCore中的多个穿透

最新的Mediatr和具有同步方法的处理程序Handle:并非所有代码路径都返回值"

Take()方法如何与IAsyncEnumerable一起使用

带有列表参数的表达式树

为什么方法的值在SELECT方法中不会更改?

RX操作员使用先前值进行扫描,信号来自值本身

MSI无法将快捷方式添加到启动文件夹

.NET8Blazor-为什么Rapzor渲染在for循环之后显示?

如何使用EPPlus C#在单个单元格中可视化显示多行文字

try 访问字典中的模拟对象时引发KeyNotFoundException

.NET文档对继承的困惑