Wäre es nicht ausreichend, öffentliche Methoden bereitzustellen und die Aktion aus der Sicht direkt an diese öffentliche Methode zu binden? Warum existiert ICommand?
Sie können nicht auf ein Verfahren in XAML binden. Du brauchst ein Objekt. Daher müssen Sie die Methode in ein Objekt einbinden.
Es ist ein häufiges Muster in der Benutzeroberfläche, dass einige Aktionen nicht immer verfügbar sind. Im Anmeldeformular wird die Login-Aktion nur verfügbar, wenn Sie den Benutzernamen eingeben. In MS Word sind die Aktionen zum Kopieren oder Ausschneiden nur verfügbar, wenn Sie etwas auswählen. Andernfalls sind die Schaltflächen deaktiviert und die Tastaturkürzel sind inaktiv.
- Es handelt sich um ein allgemeines Muster. Dieser Befehl kann mit anderen Parametern aufgerufen werden.
Plain Eventhandler nicht diesen Anforderungen gerecht zu werden, aber ICommand
Server genau diese Zwecke:
public interface ICommand
{
void Execute(object parameter);
bool CanExecute(object parameter);
event EventHandler CanExecuteChanged;
}
- Es wickelt Methode auf ein Objekt
- Er sagt, ob verfügbar zu befehlen oder nein ist, so Die UI-Komponente (in der Regel eine Schaltfläche oder ein Menüeintrag) kann dies widerspiegeln.
- Außerdem werden die UI-Komponenten benachrichtigt, dass sich die Verfügbarkeit des Befehls geändert hat, sodass die Benutzeroberfläche reflnken kann ect es. Jetzt
, lassen Sie uns Copy & Paste Szenario in Betracht ziehen. Mit ICommand das Markup kann wie folgt aussehen:
<Button Content="Paste" Command="{Binding PasteCommand}" />
<MenuItem Header="Paste" Command="{Binding PasteCommand}" />
public ICommand PasteCommand {get;} = new DelegateCommand(Paste,() => Clipboard != null);
Wie es wie ohne ICommand
aussehen würde? Um es einfacher zu machen, kann erwägen, dass XAML erlauben würde, Methoden zu binden:
<Button Content="Paste" Click="{Binding Paste}" IsEnabled="{Binding CanPaste}" />
<MenuItem Header="Paste" Click="{Binding Paste}" IsEnabled="{Binding CanPaste}"/>
public void Paste() {....}
private bool _canPaste;
public bool CanPaste
{
get { return _canPaste }
set
{
if (_canPaste != value)
{
_canPaste = value;
OnNotifyPropertyChanged(nameof(CanPaste);
}
}
}
wie Sie sehen können, ist es nicht nur ausführliches, aber es ist auch Verletzung von DRY-Prinzip. Sie müssen sowohl Paste
als auch CanPaste
Bindung jedes Mal angeben, wenn Sie den Befehl verwenden möchten. Was wäre, wenn Sie ohne CanPaste gestartet wären und später hinzufügen wollten? Dann müssten Sie die CanPaste-Bindung bei jedem Aufruf des Aufrufs Paste
hinzufügen. Ich garantiere dir, dass du es irgendwo vergessen würdest.
Nun, wenn Sie dies in WPF tat
<Button Content="Paste" Click="Call_ViewModel_Paste" />
//in codebehind:
void Call_ViewModel_Paste(oobject sender, RoutedEventArgs e)
{
ViewModel.Call_ViewModel_Paste();
}
oder schließlich:
<Button Content="Paste">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:CallMethodAction MethodName="Paste" TargetObject="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
Beide Ansätze richtig sind, folgen sie MVVM priciples und arbeitet ohne ICommand, aber Wie Sie sehen können, ist keiner so elegant wie ICommand
* "Binden Sie die Aktion aus der Ansicht direkt an diese öffentliche Methode" * - das ist es, was 'ICommand' genauso gut tut wie die Ansicht, wann immer Befehl ** ausgeführt werden kann. Werfen Sie einen Blick auf ['DelegateCommand'] (https://wpftutorial.net/DelegateCommand.html) es macht es einfach. – Sinatr
Einige MVVM-Frameworks wie Caliburn.Micro verwenden Namenskonventionen zum Binden von Methoden zum Anzeigen von Elementen * ohne * einen ICommand. –
Man kann relativ einfach eigene Funktionen hinzufügen mit * angehängtem Verhalten * (reines MVVM): Sie können bestimmte View-Ereignisse abonnieren (Sie können dies im Code-hinter sehen, aber das wäre schmutzig MVVM), um bestimmte Methoden von ViewModel aufzurufen (direkt, über Schnittstelle oder durch Reflexion). 'ICommand' war ein absolutes Minimum, was WPF benötigt, nämlich löst es Probleme, wenn Menüpunkte/Schaltflächen deaktiviert werden, z. für das Szenario 'Kopieren' /' Einfügen'. Nichts mehr. In der Tat kann 'ButtonBase.Command' ein einfacher' Click'-Event-Handler sein, Sie können die ViewModel-Methode dort sofort aufrufen. – Sinatr