Enabling a content dialog button

Eduardo Gomez 4,216 Reputation points
2026-01-10T04:14:27.9433333+00:00

I am using MVVM with the Microsoft mvvm toolkit

I am trying to enable the button "connect" when I typed or paste my connection string

Model

    public partial class DatabaseProperties : ObservableObject {
        [ObservableProperty]
        public partial string? DatabaseUrl { get; set; }
    }
}


viewmodel

   public partial class ConnectDialogViewModel : ObservableObject {
       [ObservableProperty]
       public partial DatabaseProperties DatabaseProperties { get; set; } = new DatabaseProperties();
       public bool CanConnect => !string.IsNullOrWhiteSpace(DatabaseProperties?.DatabaseUrl);
       partial void OnDatabasePropertiesChanged(DatabaseProperties oldValue, DatabaseProperties newValue) {
           if(oldValue != null)
               oldValue.PropertyChanged -= DatabaseProperties_PropertyChanged;
           if(newValue != null)
               newValue.PropertyChanged += DatabaseProperties_PropertyChanged;
           OnPropertyChanged(nameof(CanConnect));
       }
       private void DatabaseProperties_PropertyChanged(object? sender, PropertyChangedEventArgs e) {
           if(e.PropertyName == nameof(DatabaseProperties.DatabaseUrl)) {
               OnPropertyChanged(nameof(CanConnect));
           }
       }
   }

view

    public sealed partial class ConnectDialog : ContentDialog {

        public ConnectDialogViewModel? ViewModel { get; set; }

        public ConnectDialog(ConnectDialogViewModel connectDialogViewModel) {
            InitializeComponent();

            // Use non-nullable property
            ViewModel = connectDialogViewModel ?? throw new ArgumentNullException(nameof(connectDialogViewModel));

            this.DataContext = ViewModel;

            // Subscribe to property changes
            ViewModel.PropertyChanged += ViewModel_PropertyChanged;

            // Initialize button state
            IsPrimaryButtonEnabled = ViewModel.CanConnect;
        }

        private void ViewModel_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) {
            if(e.PropertyName == nameof(ConnectDialogViewModel.CanConnect)) {
                if(sender is ConnectDialogViewModel vm) {
                    IsPrimaryButtonEnabled = vm.CanConnect;
                }
            }
        }
    }
}


User's image

Developer technologies | Universal Windows Platform (UWP)
0 comments No comments
{count} votes

Answer accepted by question author
  1. Karthik Sekar 75 Reputation points
    2026-01-10T05:18:57.8466667+00:00

    Bind the dialog’s IsPrimaryButtonEnabled directly to CanConnect instead of toggling it in code-behind, and ensure CanConnect raises PropertyChanged whenever DatabaseUrl changes.

    0 comments No comments

Answer accepted by question author
  1. Marcin Policht 72,700 Reputation points MVP Volunteer Moderator
    2026-01-10T04:27:28.36+00:00

    You shouldn't have to manually wire PropertyChanged and bubble it up. With the MVVM Toolkit you should be able to expose the inner property directly and bind to it.

    As far as I can tell, you might be able to fix the issue by exposing DatabaseUrl on the ViewModel and compute CanConnect from that.

    ViewModel

    public partial class ConnectDialogViewModel : ObservableObject
    {
        [ObservableProperty]
        private string? databaseUrl;
    
        public bool CanConnect => !string.IsNullOrWhiteSpace(DatabaseUrl);
    
        partial void OnDatabaseUrlChanged(string? oldValue, string? newValue)
        {
            OnPropertyChanged(nameof(CanConnect));
        }
    }
    

    Remove the nested DatabaseProperties and drop all manual PropertyChanged code.

    XAML binding example

    <TextBox Text="{Binding DatabaseUrl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
    

    Dialog

    public sealed partial class ConnectDialog : ContentDialog
    {
        public ConnectDialog(ConnectDialogViewModel vm)
        {
            InitializeComponent();
            DataContext = vm;
            vm.PropertyChanged += (_, e) =>
            {
                if (e.PropertyName == nameof(vm.CanConnect))
                    IsPrimaryButtonEnabled = vm.CanConnect;
            };
            IsPrimaryButtonEnabled = vm.CanConnect;
        }
    }
    

    If you must keep the nested model, add one line to your nested property handler:

    private void DatabaseProperties_PropertyChanged(object? sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(DatabaseProperties.DatabaseUrl))
            OnPropertyChanged(nameof(CanConnect));
    }
    

    and in XAML bind directly to the nested property.

    <TextBox Text="{Binding DatabaseProperties.DatabaseUrl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
    

    The key is UpdateSourceTrigger=PropertyChanged so changes propagate and CanConnect is based on the actual string being edited.


    If the above response helps answer your question, remember to "Accept Answer" so that others in the community facing similar issues can easily find the solution. Your contribution is highly appreciated.

    hth

    Marcin


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.