【问题标题】:WPF input validation issue when using async call使用异步调用时的 WPF 输入验证问题
【发布时间】:2021-04-24 15:19:33
【问题描述】:

我在使用异步验证时遇到验证错误。

我正在使用 DevExpress 文本框,并通过 validate 方法使用异步调用来验证数字是否唯一。其他本地检查显示验证错误,但是当我进入第三步(异步)时,它没有显示错误。

我确定这是由于调用的异步性质造成的。我已经尝试过使用 async/await、Task.Runin 这么多组合,以至于我数不清,但仍然无法使其工作。

xaml:

<dxe:TextEdit
  EditValue="{Binding Mode=TwoWay, NotifyOnSourceUpdated=True, Path=Dto.Number, updateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
  InvalidValueBehavior="AllowLeaveEditor"
  IsEnabled="{Binding IsNew, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}"
  NullText="Enter number"
  ValidateOnTextInput="True"
  Validate="NumberOnValidate" />

xaml.cs

private void NumberOnValidate(object sender, ValidationEventArgs e)
{
  if (!((TextEdit) sender).IsEnabled)
  {
    return;
  }

  //Task.Run(async () => {
  e.ErrorContent = RequiredValidationRule.GetErrorMessage("Number", e.Value);

  if (string.IsNullOrWhiteSpace(e.ErrorContent?.ToString()))
  {
    e.ErrorContent = StringMaxlengthValidationRule.GetErrorMessage("Number", 255, e.Value);

    if (string.IsNullOrWhiteSpace(e.ErrorContent?.ToString()))
    {
      var dataContext = (UpsertViewModel) DataContext;
      Task.Run(async () =>
      {
        e.ErrorContent = await Validation.IsNumberUnique(dataContext.HubConnection, dataContext.SelectedType, e.Value);
      });
    }
  }

  if (!string.IsNullOrWhiteSpace(e.ErrorContent?.ToString()))
  {
    e.IsValid = false;
  }

  //});
}

验证:

public static async Task<string> IsNumberUnique(IHubConnection hubConnection, EnumType type, object fieldValue)
{
  if (fieldValue == null || string.IsNullOrWhiteSpace(fieldValue.ToString()))
  {
    return "Cannot validate the uniqueness of the number field because it is empty.";
  }

  //Task.Run(async () =>
  //{
    try
    {
      var response = false;

      switch (type)
      {
        case EnumType.T1:
          response = await hubConnection.T1IsNumberUnique(fieldValue.ToString());

          break;

        case EnumType.T2:
          response = await hubConnection.T2IsNumberUnique(fieldValue.ToString());

          break;

        case EnumType.T3:
          response = await hubConnection.T3IsNumberUnique(fieldValue.ToString());

          break;
      }

      if (!response)
      {
        return "The number field must be unique.";
      }
    }
    catch (Exception ex)
    {
      return $"Error validating the number field for uniqueness. Exception: {ex}";
    }

    return string.Empty;
  //});

  //return string.Empty;
}

我想我已经尝试了所有我能想到的方法,但是获取异步调用的短暂延迟使验证方法跳过响应并且它没有在 GUI 中注册。

在调试时,我可以看到验证发生后异步响应即将到来,那么如何对齐线程以使验证“等待”异步响应。

【问题讨论】:

    标签: wpf validation asynchronous devexpress-wpf


    【解决方案1】:
    Task.Run(async () =>
    {
        e.ErrorContent = await Validation.IsNumberUnique(dataContext.HubConnection, dataContext.SelectedType, e.Value);
    });
    

    这段代码在另一个线程中触发异步任务。然后,您的原始验证线程会立即继续进行。

    我猜你可以阻止异步方法的Result,但这会否定异步的优势,并且会在 UI 运行时锁定它。

    我怀疑你需要做一些 hacky,比如在异步方法完成时再次引发 PropertyChanged,这将强制 WPF 再次验证,并使用某种标志来防止异步调用再次运行。

    【讨论】:

    • 我也尝试过直接等待/异步,但结果相同。有趣的是,现在所有的异步都是标准的,没有可用的异步验证
    猜你喜欢
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多