Я очень ценю сочетание использования свойств CanExecute, NotifyCanExecuteChangedFor и AsyncRelayCommand<T>.IsRunning для запуска/остановки ActivityIndicator и отключения/включения кнопки Command без необходимости отслеживать логические свойства во всей ViewModel, как описано в этой превосходной записи блога .
И все же мне интересно, а как насчет всех остальных флагов?
Например, следующий пример кода поддерживает файл XAML, содержащий один элемент управления Picker (здесь нет кнопок). Перед загрузкой коллекции необходимо запустить ActivityIndicator и отключить Picker, а после загрузки коллекции флаги меняются местами. Поскольку приложение усложняется, придется добавлять другие флаги.
Есть ли лучший способ выполнить эти задачи, не полагаясь на логические флаги?
public partial class TestViewModel: ObservableObject
{
[ObservableProperty]
private Book _selectedBook;
[ObservableProperty]
ObservableCollection<Book> _books;
[ObservableProperty]
bool _showIndicator;
[ObservableProperty]
bool _pickerEnabled;
public TestViewModel()
{
BooksService();
}
async Task BooksService()
{
ShowIndicator = true;
PickerEnabled = false; //by default
await Task.Delay(TimeSpan.FromSeconds(5));
Books = await FetchBooks();
ShowIndicator = false;
PickerEnabled = true;
}
}





Как предположил @LiqunShen-MSFT в комментарии, в итоге я положился на конвертеры. Но вместо того, чтобы писать свои собственные, я использовал готовые, доступные в .NET Maui Community Toolkit. В частности, IsListNullOrEmptyConverter и IsListNotNullOrEmptyConverter.
<Grid>
<VerticalStackLayout Padding = "20" Spacing = "20" VerticalOptions = "Fill">
<Picker Title = "Select Book"
ItemsSource = "{Binding Books}"
IsEnabled = "{Binding Books,
Converter = {StaticResource IsListNotNullOrEmptyConverter}}" />
</VerticalStackLayout>
<ActivityIndicator
IsVisible = "{Binding Books,
Converter = {StaticResource IsListNullOrEmptyConverter}}"
IsRunning = "{Binding Books,
Converter = {StaticResource IsListNullOrEmptyConverter}}" />
</Grid>
Рад, что вы решили эту проблему, и спасибо, что поделились! @usefulBee! Еще одно небольшое предложение, если вы хотите настроить свой собственный конвертер, а именно Использование параметров конвертера.
Предположим, у вас много флагов, и вы можете написать много конвертеров. Если вы используете Converter Parameters, вы можете поместить всю логику в один конвертер в зависимости от параметров, например:
<Label
Text = "{Binding MyText,Converter = {StaticResource myconverter},ConverterParameter=IsListNotNullOrEmpty}"
для индивидуального конвертера
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
string str = (string)value;
if ((string)parameter == "IsListNotNullOrEmpty")
{
//your logic
}else if ((string)parameter == "b")
{
//your logic
}
...
}
Вышеупомянутое - небольшое предложение от меня. И набор инструментов сообщества .NET Maui хорош!
Хотите меньше флагов? Вы можете попробовать использовать Конвертеры значений привязки.