[英]Call method when ObservableProperty changes using CommunityToolkit.Mvvm
I'm implementing auto complete feature in my .NET MAUI app and I'm using CommunityToolkit.Mvvm
code generators in my view model to handle observable properties.我正在我的 .NET MAUI 应用程序中实现自动完成功能,并且在我的视图 model 中使用
CommunityToolkit.Mvvm
代码生成器来处理可观察的属性。
I have the following code and I'm trying call GetSuggestions()
method when the SearchText
changes.我有以下代码,我正在尝试在
SearchText
更改时调用GetSuggestions()
方法。
[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;
}
}
This is giving me the following error:这给了我以下错误:
The target(s) of [NotifyCanExecuteChangedFor] must be an accessible IRelayCommand property, but "GetSuggestions" has no matches in type MyViewModel.
[NotifyCanExecuteChangedFor] 的目标必须是可访问的 IRelayCommand 属性,但“GetSuggestions”在类型 MyViewModel 中没有匹配项。
What am I doing wrong here?我在这里做错了什么?
I guess there are two problems here.我想这里有两个问题。
That happens because GetSuggestions
is not a Command.发生这种情况是因为
GetSuggestions
不是命令。 Try adding the [RelayCommand]
attribute to your method.尝试将
[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;
}
}
Then link NotifyCanExecuteChangedFor
to the autogenerated command.然后将
NotifyCanExecuteChangedFor
链接到自动生成的命令。
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(GetSuggestionsCommand))]
string searchText;
You need to你需要
call GetSuggestions() method when the SearchText changes.
SearchText 更改时调用 GetSuggestions() 方法。
The NotifyCanExecuteChangedFor
attribute doesn't do that. NotifyCanExecuteChangedFor
属性不这样做。
In the autogenerated source code you should find an empty partial method called OnSearchTextPropertyChanged
.在自动生成的源代码中,您应该找到一个名为
OnSearchTextPropertyChanged
的空部分方法。 Try implementing it.尝试实施它。
partial void OnSearchTextPropertyChanged(string value)
{
GetSuggestions();
}
If this is what you're searching for, GetSuggestions
doesn't need to be marked with the RelayCommand
attribute.如果这是您要搜索的内容,
GetSuggestions
不需要使用RelayCommand
属性进行标记。
Only meant as more of an amendment of @RMinato's answer.仅意味着对@RMinato 的回答的更多修正。
As my comment say: "While most of this was helpful, I need to do a few things different including using the [RelayCommand]
and calling the method inside my OnPropChanged
method to be Task.Run(() => this.MyMethodAsync()).Wait();
".正如我的评论所说:“虽然其中大部分内容都有帮助,但我需要做一些不同的事情,包括使用
[RelayCommand]
并将我的OnPropChanged
方法中的方法调用为Task.Run(() => this.MyMethodAsync()).Wait();
”。
My code looks like:我的代码看起来像:
[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;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.