我正在尝试实现 RelayCommand 的内置 IsRunning 属性,如 Julian 所描述,但由于某种原因,唯一有效的场景是使用“保存”按钮命令时。
这是我迄今为止尝试过的:
XAML 结构
<Grid>
<VerticalStackLayout Padding="20" Spacing="20" VerticalOptions="Fill">
<Picker Title="Pick Book"
ItemsSource="{Binding Books}"
SelectedItem="{Binding SelectedBook}"
ItemDisplayBinding="{Binding BookName}">
</Picker>
<Picker Title="Pick Chapter"
ItemsSource="{Binding Chapters}"
SelectedItem="{Binding SelectedChapter}"
ItemDisplayBinding="{Binding ChapterName}" />
<Button Text="Save"
Command="{Binding SaveButtonCommand}" />
</VerticalStackLayout>
<ActivityIndicator x:Name="booksActivity"
IsVisible="True"
IsRunning="{Binding BooksServiceCommand.IsRunning}"/>
<ActivityIndicator x:Name="chaptersActivity"
IsVisible="True"
IsRunning="{Binding ChaptersServiceCommand.IsRunning}"/>
<ActivityIndicator x:Name="buttonActivity"
IsVisible="True"
IsRunning="{Binding SaveButtonCommand.IsRunning}"/>
</Grid>
ViewModel 结构
public partial class BooksViewModel : ObservableObject
{
public class Book { public int BookId { get; set; } public string BookName { get; set; } }
public class Chapter { public string ChapterName { get; set; } }
[ObservableProperty]
private Book _selectedBook;
[ObservableProperty]
Chapter _selectedChapter;
[ObservableProperty]
ObservableCollection<Book> _books;
[ObservableProperty]
ObservableCollection<Chapter> _chapters;
从构造函数调用 BooksService 不会触发 ActivityIndicator 环
public BooksViewModel()
{
Task.Run(() => BooksServiceAsync());
}
[RelayCommand]
public async Task BooksServiceAsync()
{
// Run ActivityIndicator ring here
await Task.Delay(TimeSpan.FromSeconds(5));
Books = await Task.Run(() => FetchBooks());
}
private ObservableCollection<Book> FetchBooks()
{
return [
new Book { BookName = "Book1"},
new Book { BookName = "Book2" },
new Book { BookName = "Book3" }];
}
OnSelectedBookChanged 不会触发 ActivityIndicator 环
partial void OnSelectedBookChanged(Book value)
{
Task.Run(() => ChaptersServiceAsync(value.BookId));
}
[RelayCommand]
public async Task ChaptersServiceAsync(int bookId)
{
// Run ActivityIndicator ring here
await Task.Delay(TimeSpan.FromSeconds(5));
Chapters = await Task.Run(() => FetchChapters());
}
private ObservableCollection<Chapter> FetchChapters()
{
return [
new Chapter { ChapterName = "Chapter1"},
new Chapter { ChapterName = "Chapter2" },
new Chapter { ChapterName = "Chapter3" }];
}
按钮场景正在工作并成功触发 ActivityIndicator 响铃
[RelayCommand]
public async Task SaveButton()
{
// Run ActivityIndicator ring here
await Task.Delay(TimeSpan.FromSeconds(5));
}
}
这里可能出了什么问题?
我正在尝试实现 Julian 所描述的 RelayCommand 的内置 IsRunning 属性,但由于某种原因,唯一有效的方案是使用“保存”按钮命令时。
我测试了您提供的代码并重现了问题。
BooksService 和 ChaptersServiceAsync 没有触发 ActivityIndicator 环的原因是您没有使用
BooksServiceCommand
或 ChaptersServiceAsyncCommand
。当你在构造函数中输入“BooksSer”时,IDE的智能关联将显示BooksServiceCommand
:
这也说明Button Scenario正在工作并成功触发了ActivityIndicator环。
所以,如果添加一个按钮来绑定(使用)
BooksServiceCommand
,就可以触发ActivityIndicator环。
<VerticalStackLayout Padding="20" Spacing="20">
<Picker Title="Pick Book"
ItemsSource="{Binding Books}"
SelectedItem="{Binding SelectedBook}"
ItemDisplayBinding="{Binding BookName}">
</Picker>
<Picker Title="Pick Chapter"
ItemsSource="{Binding Chapters}"
SelectedItem="{Binding SelectedChapter}"
ItemDisplayBinding="{Binding ChapterName}" />
<Button Text="Save"
Command="{Binding SaveButtonCommand}" />
<Button Text="LoadBooks"
Command="{Binding BooksServiceCommand}" />
</VerticalStackLayout>