简体   繁体   中英

.Net Maui Button.IsEnabled not disabled at startup

I have this button in my MainPage.cs and am using CommunityToolkit.Maui.Markup;

new Button()
.Bind(Button.IsEnabledProperty, nameof(vm.CallButtonEnabled))
.Bind(Button.TextProperty, nameof(vm.CallButtonText))
.BindCommand(nameof(vm.CallCommand))

CallButtonEnabled = false in my viewmodel's constructor and is toggled by another buttons command.

When I use the extension methods in this order, the button is enabled at program start. I think this is because the command's button enabling mechanics are overriding the value I manually set.

If I change the extention method's order like so

new Button()
.BindCommand(nameof(vm.CallCommand))
.Bind(Button.IsEnabledProperty, nameof(vm.CallButtonEnabled))
.Bind(Button.TextProperty, nameof(vm.CallButtonText))

with the BindCommand coming first, the button is now disabled at program start; confirming my suspicion.

My question being; is this just something that I have to be aware of, making sure that the .BindCommand is called first, or is there another way to get the results I want?

EDIT 6-14-22 Here is my minimal reproducible example as requested.

MauiProgram.cs

using CommunityToolkit.Maui;
using CommunityToolkit.Maui.Markup;

namespace MauiApp1;

public static class MauiProgram
{
   public static MauiApp CreateMauiApp()
   {
      var builder = MauiApp.CreateBuilder();
      builder
         .UseMauiApp<App>()
         .UseMauiCommunityToolkit()
         .UseMauiCommunityToolkitMarkup()
         .ConfigureFonts(fonts =>
         {
            fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
         });

      builder.Services.AddSingleton<MainPage, MainPage>();
      builder.Services.AddSingleton<MainPageViewModel, MainPageViewModel>();

      return builder.Build();
   }
}

MainPage.cs

using CommunityToolkit.Maui.Markup;

namespace MauiApp1;

public class MainPage : ContentPage
{
   public MainPage(MainPageViewModel vm)
   {
      BindingContext = vm;

      Content = new ScrollView
      {
         Content = new VerticalStackLayout
         {
            Children =
            {
               new Button
               {
                  Text = "Toggle ther button enabled"
               }
               .BindCommand(nameof(vm.ButtonClickedCommand)),

               // This button works as expected and is disabled at startup
               //new Button()
               //.BindCommand(nameof(vm.DisplayAlertCommand))   // <-----
               //.Bind(Button.TextProperty, nameof(vm.ButtonText))
               //.Bind(Button.IsEnabledProperty, nameof(vm.ButtonEnabled)),
                    
               // This button is enabled at startup but the text still reads "Disabled"
               // On first click of the toggle button, this text changes to "Enabled" and the Button is still enabled
               // Everything works as expected on subsequest pressess of the toggle button.
               new Button ()
               .Bind(Button.TextProperty, nameof(vm.ButtonText))
               .Bind(Button.IsEnabledProperty, nameof(vm.ButtonEnabled))
               .BindCommand(nameof(vm.DisplayAlertCommand)),   // <-----
            }
         }
      };
   }
}

MainPageViewModel.cs

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace MauiApp1;

public partial class MainPageViewModel : ObservableObject
{
   [ObservableProperty]
   private bool _buttonEnabled = false;

   [ObservableProperty]
   private string _buttonText = "Disabled";

   [RelayCommand]
   private void OnButtonClicked()
   {
      ButtonEnabled = !ButtonEnabled;
      ButtonText = ButtonEnabled ? "Enabled" : "Diabled";
   }

   [RelayCommand]
   private async void DisplayAlert()
   {
      await Application.Current.MainPage.DisplayAlert("", "Other Button Clicked", "OK");
   }
}

These three files are the only changes I made to the default .NET Maui template, except for: deleting MainPage.xaml , renaming MainPage.xaml.cs -> MainPage.cs , and installing the NuGet packages used in the above code.

I tested this example on

Microsoft Visual Studio Community 2022 (64-bit) - Preview; Version 17.3.0 Preview 2.0

and am still getting the undesired behavior.

According to my test , we just need to set BindingContext before creating the binding relationship , in this case no matter we put BindCommand before or after , it will work as expected .

Sample code

ViewModel vm = new ViewModel();
BindingContext = vm;    //look at this line 

Button btn = new Button();

btn.BindCommand(nameof(vm.CallCommand))
   .Bind(Button.IsEnabledProperty, nameof(vm.CallButtonEnabled))
   .Bind(Button.TextProperty, nameof(vm.CallButtonText)); 


//  the following code is also ok
//btn.Bind(Button.IsEnabledProperty, nameof(vm.CallButtonEnabled))
//   .Bind(Button.TextProperty, nameof(vm.CallButtonText))
//   .BindCommand(nameof(vm.CallCommand));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM