Domanda

Da quello che ho capito, l'obiettivo del modello di comando è di aiutare a separare l'interazione dell'interfaccia utente dalla logica dell'applicazione. Con i comandi correttamente implementati, fai clic su " Stampa " la voce di menu potrebbe provocare una catena di interazione come questa:

(button) ---click executes command----> (command) ---calls Print() in app logic ---> (logic)

Questo ti incoraggia a separare l'interfaccia utente dalla logica dell'applicazione.

Ho osservato i comandi WPF e per la maggior parte vedo come hanno implementato questo modello. Tuttavia, mi sento in una certa misura che hanno complicato il modello di comando e sono riusciti a implementarlo in modo tale da scoraggiarti dal separare l'interfaccia utente dalla logica dell'applicazione.

Ad esempio, considera questa semplice finestra di WPF che ha un pulsante per incollare il testo nella casella di testo:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.CommandBindings>
        <CommandBinding Command="ApplicationCommands.Paste"
                        Executed="CommandBinding_Executed"/>
    </Window.CommandBindings>
    <StackPanel>
        <TextBox x:Name="txtData" />
        <Button Command="Paste" Content="Paste" />
    </StackPanel>
</Window>

Ecco il code-behind:

namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }

        private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ApplicationCommands.Paste.Execute(null, txtData);
        }
    }
} 

Cosa ho guadagnato dal comando? Mi sembra che avrei potuto inserire altrettanto facilmente il codice dal gestore eventi di associazione comandi nell'evento Click del pulsante. Certo, ora posso associare più elementi dell'interfaccia utente al comando Incolla e devo usare solo un gestore eventi, ma cosa succede se voglio incollare in diverse caselle di testo? Dovrei rendere la logica del gestore eventi più complicata o scrivere più gestori eventi. Quindi ora sento di avere questo:

(button) ---executes Routed Command---> (Window) ---executes command binding----(command binding)
(logic) <---calls application logic--- (event handler) <-----raises event --------------|

Cosa mi sto perdendo qui? A me sembra un ulteriore livello di indiretto.

È stato utile?

Soluzione

Oltre alle cose già menzionate, ciò che hai dimenticato nel tuo specifico esempio Incolla sono le proprietà CommandTarget e CommandParameter. Per Incolla, puoi specificare un oggetto TextBox impostando come CommandTarget.

Queste proprietà sono assolutamente essenziali quando si desidera utilizzare lo stesso RoutedCommand da controlli diversi. Consentono di fornire al gestore eseguito alcune informazioni sul contesto in cui viene invocato il comando.

Altri suggerimenti

Potresti avere dei concetti confusi.

L'interfaccia ICommand supporta il modello di comando. Ciò ti consente di astrarre le azioni dell'utente in una classe riutilizzabile.

I comandi indirizzati sono un'implementazione particolare di ICommand che cerca i gestori nell'albero visivo. Sono particolarmente utili per i comandi che possono essere implementati da molti controlli diversi e si desidera che il controllo corrente lo gestisca. Pensa a copia / incolla. Potrebbero esserci un sacco di controlli che potrebbero gestirlo, ma usando il comando instradato, il sistema di comando instradato troverà automaticamente il controllo corretto per gestire il comando in base al focus.

Preferirei usare i comandi RoutedCommands e RoutedUICcom quando si creano controlli. Ad esempio TextBox implementa UndoCommand per te e l'input guseture è già associato a Ctrl + Z . Quando si creano i modelli di visualizzazione, tuttavia, la mia preferenza è per un ICommand personalizzato con implementazioni interne di Execute e CanExecute. Il DelegateCommand fornisce questo in Prism. Ciò consente al designer view / xaml di preoccuparsi solo del comando e non dei gestori Execute / CanExecute corretti da utilizzare. Ciò consentirebbe un modello di vista più espressivo.

ps. I comandi delegati non funzionano ancora (elegantemente) con InputBindings. Qualcuno di Microsoft può risolvere questo problema per favore!

Possono essere eccessivi per alcune cose, ma ottieni alcuni benefici come CanExecute che può abilitare / disabilitare automaticamente pulsanti / voci di menu quando il comando non è disponibile (come nessun testo selezionato ecc.). Puoi anche eseguire comandi in Blend, senza utilizzare alcun codice, il che è ottimo per i designer.

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