Perché un pulsante è abilitato se il collegamento Command si risolve in null?

OK, XAML è abbastanza semplice e usa MVVM per collegarsi a un ICommand SomeCommand { get; } ICommand SomeCommand { get; } proprietà su un modello di vista:

  

Se SomeCommand restituisce null , il pulsante è abilitato. (Nulla da fare con il CanExecute(object param) su ICommand , perché non c’è un’istanza per chiamare quel metodo su)

E ora la domanda: perché il pulsante è abilitato? Come faresti a lavorarci?

Se si preme il pulsante “abilitato”, ovviamente non viene chiamato nulla. È brutto che il pulsante sia abilitato.

È abilitato perché è lo stato predefinito. Disabilitarla automaticamente sarebbe una misura arbitraria che dà origine ad altri problemi.

Se si desidera che un pulsante senza un comando associato sia disabilitato, associare la proprietà IsEnabled a SomeCommand utilizzando un convertitore appropriato, ad esempio:

 [ValueConversion(typeof(object), typeof(bool))] public class NullToBooleanConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return value !== null; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException(); } } 

Il mio collega ha trovato una soluzione elegante: utilizzando un valore di fallback vincolante!

 public class NullCommand : ICommand { private static readonly Lazy _instance = new Lazy(() => new NullCommand()); private NullCommand() { } public event EventHandler CanExecuteChanged; public static ICommand Instance { get { return _instance.Value; } } public void Execute(object parameter) { throw new InvalidOperationException("NullCommand cannot be executed"); } public bool CanExecute(object parameter) { return false; } } 

E poi XAML assomiglia a:

  

Il vantaggio di questa soluzione è che funziona meglio se si infrange Law of Demeter e si hanno alcuni punti nel percorso di binding, in cui ogni istanza potrebbe diventare null .

Molto simile alla risposta di Jon, è ansible utilizzare uno stile con un trigger per contrassegnare i pulsanti che dovrebbero essere disabilitati quando non è impostato alcun comando.

  

Preferisco questa soluzione perché affronta il problema molto direttamente e non richiede nuovi tipi.