使用CommunityToolkit.Mvvm在ObservableProperty改变时调用方法

问题描述 投票:0回答:3

我正在我的 .NET MAUI 应用程序中实现自动完成功能,并且我在视图模型中使用

CommunityToolkit.Mvvm
代码生成器来处理可观察的属性。

我有以下代码,当

GetSuggestions()
发生变化时,我尝试调用
SearchText
方法。

[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(GetSuggestions))]
string searchText;

[ObservableProperty]
bool showSuggestions;

ObservableCollection<string> Suggestions { get; } = new();

private async Task GetSuggestions()
{
   if(string.IsNullOrEmpty(SearchText) || SearchText.Length < 3)
      return;

   var data = await _myApiService.GetSuggestions(SearchText.Trim());
   if(data != null && data.Count > 0)
   {
      Suggestions.Clear();
      foreach(var item in data)
         Suggestions.Add(item);

      ShowSuggestions = true;
   }
}

这给了我以下错误:

[NotifyCanExecuteChangedFor] 的目标必须是可访问的 IRelayCommand 属性,但“GetSuggestions”在类型上没有匹配项 我的视图模型。

我在这里做错了什么?

c# observablecollection community-toolkit-mvvm
3个回答
15
投票

我想这里有两个问题。

为什么会出现这个错误?

发生这种情况是因为

GetSuggestions
不是命令。 尝试将
[RelayCommand]
属性添加到您的方法中。

[RelayCommand]
private async Task GetSuggestions()
{
    if(string.IsNullOrEmpty(SearchText) || SearchText.Length < 3)
       return;

    var data = await _myApiService.GetSuggestions(SearchText.Trim());
    if(data != null && data.Count > 0)
    {
        Suggestions.Clear();
        foreach(var item in data)
        Suggestions.Add(item);

        ShowSuggestions = true;
    }
}

然后将

NotifyCanExecuteChangedFor
链接到自动生成的命令。

[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(GetSuggestionsCommand))]
string searchText;

第二个。

你需要

当 SearchText 更改时调用 GetSuggestions() 方法。

NotifyCanExecuteChangedFor
属性不会这样做。

在自动生成的源代码中,您应该找到一个名为

OnSearchTextPropertyChanged
的空部分方法。尝试实施它。

partial void OnSearchTextPropertyChanged(string value)
{
    GetSuggestions();
}

如果这就是您要搜索的内容,则无需使用

GetSuggestions
属性标记
RelayCommand


0
投票

仅意味着对@RMinato 答案的更多修正。

正如我的评论所说:“虽然其中大部分都有帮助,但我需要做一些不同的事情,包括使用

[RelayCommand]
并将我的
OnPropChanged
方法中的方法调用为
Task.Run(() => this.MyMethodAsync()).Wait();
”。

我的代码如下所示:

[QueryProperty(nameof(Course), nameof(Course))]
public partial class CourseDetailViewModel : BaseViewModel
{
    private readonly CourseService courseService;

    public CourseDetailViewModel(CourseService courseService)
    {
        this.courseService = courseService;
    }

    [ObservableProperty]
    [NotifyCanExecuteChangedFor(nameof(GetCourseDetailCommand))]
    Course course;

    partial void OnCourseChanged(Course value)
    {
        Task.Run(() => this.GetCourseDetailAsync()).Wait();
    }

    [RelayCommand]
    public async Task GetCourseDetailAsync()
    {
        if (GetCourseDetailCommand.IsRunning) return;

        try
        {
            IsBusy = true;

            course = await courseService.GetCourseDetailAsync(course.Id);
        }
        catch (Exception ex)
        {
            Debug.WriteLine($"Failed to get course detail. Error: {ex.Message}");
            await Shell.Current.DisplayAlert("Error!",
                $"Failed to get course detail: {ex.Message}", "OK");
            throw;
        }
        finally
        {
            IsBusy = false;
        }
    }
}

0
投票

对于更新的毛伊岛解决方案,使用社区工具包,每个可观察的属性都有一个等效的部分 On-PropertyName-Changed 事件。只需说明这应该是什么,然后您就可以离开。

此答案中的示例

© www.soinside.com 2019 - 2024. All rights reserved.