Come associare proprietà IsEnabled di un ComboBoxItem al risultato del metodo di CanExecute di un comando

StackOverflow https://stackoverflow.com/questions/2320553

Domanda

Ho un'implementazione SplitButton personalizzato in cui contiene una casella combinata con diversi ComboBoxItems legati ai comandi. Posso legarsi al nome, e le proprietà di testo del comando più che bene, ma non hanno modo di legare del ComboBoxItem IsEnabled struttura al risultato di CanExecute il metodo di un comando perché è un metodo. C'è qualche sintassi che io sono a conoscenza di metodi per il legame alla o c'è qualche inganno che mi aiuterà a legarsi a CanExecute.

A proposito, ho pensato di usare una consuetudine ValueConverter tranne che mi sono reso conto che probabilmente non avrebbe ricevuto alcun aggiornamento quando CanExecute si rivaluta in quanto non è una proprietà e dal momento che i miei comandi non sono oggetti di business . Sta cercando di me che avrei potuto creare un ViewModel per un comando a questo punto utilizzare solo all'interno del mio controllo SplitButton personalizzato ma che sembra un po 'fuori bordo per me.

È stato utile?

Soluzione 2

Un'altra soluzione per ViewModel. Qui di seguito è il modo che ho usato un ViewModel per risolvere il mio problema. E si prega di notare che il metodo NotifyPropertyChanged nifty è parte della mia classe di base ViewModel.

public class RoutedUICommandViewModel : ViewModel
{
    private RoutedUICommand _command;
    private IInputElement _target;

    public string Name { get { return _command.Name; } }

    public string Text { get { return _command.Text; } }

    public bool CanExecute
    {
        get
        {
            return _command.CanExecute(null, _target);
        }
    }

    public RoutedUICommand Command { get { return _command; } }

    public RoutedUICommandViewModel(ReportCommand command, IInputElement target)
    {
        _command = command;
        _target = target;
        _command.CanExecuteChanged += _command_CanExecuteChanged;
    }

    private void _command_CanExecuteChanged(object sender, EventArgs e)
    {
        base.NotifyPropertyChanged(() => this.CanExecute);
    }
}

Altri suggerimenti

È possibile inserire un pulsante (se non avete uno nel ControlTemplate legato alla ICommand) all'interno ItemContainerStyle (stile ComboBoxItem) e legare il comando ad esso E aggiungere un trigger per controllare il Button.IsEnabled e impostare il valore al ComboBoxItem. Quindi qui abbiamo usato come un pulsante CommandSource solo per ottenere l'IsEnabled da CanExeute. È possibile impostare altezza e la larghezza del pulsante a zero

 <ControlTemplate....>
   <Grid ...
       <Button x:Name="dummyButton" Command="{Binding YourCommand}" ....
           ......
   </Grid>

   <ControlTemplate.Triggers>
      <Trigger SourceName="dummyButton" Property="IsEnabled" Value="False">
        <Setter Property="IsEnabled" Value="False"/>
      </Trigger>
   </ControlTemplate.Triggers>

Ho trovato questa discussione su MSDN forum dove Dr. WPF aveva raccomandato l'utilizzo di un attaccato comportamento per risolvere questo problema esatto. Ha dato l'esempio che segue di come sarebbero stati utilizzati.

<Grid behaviors:CommandBehaviors.EnablingCommand="{x:Static commands:testcommand.test}">  
  . . .  
</Grid> 

Anche se questa soluzione sembra abbastanza piacevole non sono stato in grado di dedicare il tempo per capire esattamente come questo tipo di comportamento sarebbe stato attuato e ciò che è coinvolto. Se qualcuno vorrebbe elaborare prega di fare altrimenti sarò modificare questa risposta con maggiori dettagli, se ho la possibilità di esplorare questa opzione.

Il modo in cui ho risolto questo problema nel mio codice è stato quello di aggiungere un gestore di eventi sul ComboBox per l'evento PreviewMouseDown. Ecco il gestore:

private void comboBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            ViewModel vm = this.DataContext as ViewModel;

            if (vm != null)
            {
                if (!vm.CanChangeSelection())
                {
                    e.Handled = true;
                    vm.RespondToFailedAttemptChangeUnits();
                }
            }
        }

Questa grande opera per me nel caso che ho solo bisogno di fare questo in una posizione. Si potrebbe ottenere un po 'tedius se ho avuto molte pagine come questa.

Inoltre, anche se seguo il modello MVVM, io non sono un purista -. Ritengo che questa sia una buona soluzione pratica che segue lo spirito di MVVM, se non la lettera

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top