Мауи Как отключить кнопку при использовании Command-binding

Я использую привязку команды для кнопки на Мауи. Свойство IsEnabled кнопки не работает из-за привязки команды. Даже если для IsEnable установлено значение true, команда не запускается. Как я могу отключить кнопку в классе ViewModel в конструкторе в новой команде (..), чтобы команда не срабатывала, а кнопка выглядела отключенной? (Например, переключение с одной кнопки на другую.)

На learn.microsoft.. читаю:

Предупреждение

Не используйте свойство IsEnabled кнопки, если вы используете командный интерфейс.

XAML:

<ScrollView Style = "{StaticResource mainScrollView}">
    <VerticalStackLayout>

        <HorizontalStackLayout>
            <Button Text = "Month" 
                    Command = "{Binding SetMonatCommand}"
                    Style = "{StaticResource buttonCalendar}"
                    IsEnabled = "{Binding IsListActive}"/> <!-- IsEnabled IS NOT WORKING -->
            <Button Text = "List" 
                    Command = "{Binding SetListeCommand}"
                    Style = "{StaticResource buttonCalendar}"
                    IsEnabled = "{Binding IsMonthActive}"/> <!-- IsEnabled IS NOT WORKING -->
        </HorizontalStackLayout> ...

ViewModel:

public partial class CalendarPageViewModel : ObservableObject, INotifyPropertyChanged
{
private readonly CalendarService _calendarService;

[ObservableProperty]
private bool _isMonthActive;

[ObservableProperty]
private bool _IsListActive;

public ICommand SetMonthCommand { get; set; }

public ICommand SetListCommand { get; set; }

public CalendarPageViewModel(CalendarService calendarService)
{
    _calendarService = calendarService;

    SetMonthCommand = new Command(() =>
    {
        IsMonthActive = true;
        IsListActive = !IsMonthActive;
    }); // is not called when using IsEnabled at the XAML

    SetListCommand = new Command(() =>
    {
        IsListActive = true;
        IsMonthActive = !IsListActive;
    }); // is not called when using IsEnabled at the XAML
} ....
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
133
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Если у кнопки есть атрибут Command, этот атрибут IsEnabled игнорируется, и кнопка остается активной. Однако, если вы привязываете атрибут Command, то состояние атрибута IsEnabled зависит от состояния CanExecute вашего Command. Вместо прямой привязки IsEnabled лучше включить необходимую логику в состояние CanExecute вашей команды.

public ICommand SetMonthCommand { get; set; }

public CalendarPageViewModel(CalendarService calendarService)
{
    SetMonthCommand = new Command(ExecuteSetMonthCommand, CanExecuteSetMonthCommand);
}

private void ExecuteSetMonthCommand()
{
    IsMonthActive = true;
    IsListActive = !IsMonthActive;
}

private bool CanExecuteSetMonthCommand()
{
    return IsMonthActive;
}

Прежде всего, когда вы объявили переменную, такую ​​как private bool _isMonthActive, не установив для нее значение. Будет использоваться значение логического значения по умолчанию (false). Это означает, что кнопка будет отключена первой, и команда не может быть выполнена.

Кроме того, я создал новый проект для проверки вашего кода и обнаружил, что команда не будет выполняться, хотя я установил isMonthActive и _IsListActive как истину. Поэтому я использовал RelayCommand вместо ICommand. Такой как:

 public partial class CalendarPageViewModel : ObservableObject
    {
       

        [ObservableProperty]
        private bool _isMonthActive ;

        [ObservableProperty]
        private bool _IsListActive ;


        public CalendarPageViewModel(CalendarService calendarService)
        {
             IsMonthActive = true;
             IsListActive = true;
        }
        [RelayCommand]
        public void Test1()
        {
            IsMonthActive = false;
            IsListActive = !IsMonthActive;
        }
        [RelayCommand]
        public void Test2()
        {
            IsListActive = false;
            IsMonthActive = !IsListActive;
        }
       
    }

И используйте его в xaml:

 <Button Text = "Month"
                    Command = "{Binding Test1Command}"    
                    IsEnabled = "{Binding IsListActive}"/>
 
        <Button Text = "List"
                    Command = "{Binding Test2Command}"
                    IsEnabled = "{Binding IsMonthActive}"/>
        </Button>

Команда будет выполнена. Примечание. Команда кнопки отключена, если свойство IsEnabled кнопки имеет значение false. Поэтому, если вы хотите выполнить команду, вам нужно установить для свойства кнопки IsEnabled значение true.

Ответ принят как подходящий

Вы должны использовать метод CanExecute(), чтобы для кнопки было установлено значение IsEnabled=false на основе логического свойства в вашей ViewModel. Таким образом, вам нужно только одно логическое значение, независимо от того, отображается ли месяц или список, также не забудьте вызвать NotifyCanExecuteChanged() по вашей команде, чтобы он переоценил метод CanExecute(). Вы также можете использовать удобный атрибут RelayCommand из пакета nuget CommunityToolkit.Mvvm.

        [ObservableProperty]
        private bool _IsListActive = true;

        [RelayCommand(CanExecute = nameof(CanSetMonth))]
        private void SetMonth()
        {
            IsListActive = false;
            SetMonthCommand.NotifyCanExecuteChanged();
            SetListCommand.NotifyCanExecuteChanged();
        }

        private bool CanSetMonth()
        {
            return IsListActive;
        }

        [RelayCommand(CanExecute = nameof(CanSetList))]
        private void SetList()
        {
            IsListActive = true;
            SetMonthCommand.NotifyCanExecuteChanged();
            SetListCommand.NotifyCanExecuteChanged();
        }

        private bool CanSetList()
        {
            return !IsListActive;
        }

Чтобы кнопка выглядела отключенной, вы можете использовать VisualStateManager, который уже должен быть в styles.xaml при создании нового проекта MAUI.

    <Style TargetType = "Button">
        <Setter Property = "BackgroundColor" Value = "{AppThemeBinding Light = {StaticResource Primary}, Dark = {StaticResource White}}" />
        <Setter Property = "VisualStateManager.VisualStateGroups">
            <VisualStateGroupList>
                <VisualStateGroup x:Name = "CommonStates">
                    <VisualState x:Name = "Normal" />
                    <VisualState x:Name = "Disabled">
                        <VisualState.Setters>
                            <Setter Property = "TextColor" Value = "{AppThemeBinding Light = {StaticResource Gray950}, Dark = {StaticResource Gray200}}" />
                            <Setter Property = "BackgroundColor" Value = "{AppThemeBinding Light = {StaticResource Gray200}, Dark = {StaticResource Gray600}}" />
                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateGroupList>
        </Setter>
    </Style>

XAML-код:

        <Button Text = "Set Month" Command = "{Binding SetMonthCommand}" />
        <Button Text = "Set List" Command = "{Binding SetListCommand}" />

Другие вопросы по теме