Я использую привязку команды для кнопки на Мауи. Свойство 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
} ....





Если у кнопки есть атрибут 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}" />