Pokazywanie postów oznaczonych etykietą command. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą command. Pokaż wszystkie posty

czwartek, 16 sierpnia 2012

[WPF] Commands

Komendy są pewnego rodzaju zdarzeniami opisywanymi na wyższym poziomie abstrakcji. Można też je nazwać akcjami niezależnymi od aktualnego interfejsu. Przykłady ? Kopiuj, wklej, cofnij i tak dalej. WPF wspiera znaczną ilość wbudowanych komend, a niektóre z nich są skojarzone ze skrótami klawiaturowymi systemu (np. Ctrl + C). Od strony kodu komenda musi implementować interfejs ICommand, który definiuje trzy podstawowe składniki: Execute (metoda w której zawiera się logika), CanExecute - zwraca true, jeśli można wywołać komendę oraz zdarzenie CanExecuteChanged, które jest wywoływane, gdy wartość CanExecute zmienia się. Niektóre kontrolki, takie jak np. button wystawiają property Command, gdzie przez Command Binding można zbindować się do jednej z dostępnych komend, lub stworzyć własną. Ponadto nic nie stoi na przeszkodzie, by zdefiniować własne skróry klawiaturowe do własnych komend.

Dostępne komendy w System.Windows.Input:
Poniższy przykład pokazuje jak wykorzystać kilka wbudowanych komend i zdefiniować dla nich skróty klawiszowe:

<Window x:Class="Commands.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.CommandBindings>
        <CommandBinding Command="Favorites" 
                        CanExecute="CommandBinding_CanExecute" 
                        Executed="CommandBinding_Executed" />
        <CommandBinding Command="Close" 
                        CanExecute="CommandBinding_CanExecute"
                        Executed="CommandBinding_Executed_1" />
    </Window.CommandBindings>
    <Window.InputBindings>
        <KeyBinding Command="Favorites" Key="F5" />
        <KeyBinding Command="Close" Gesture="Ctrl+q" CommandParameter="q" />
    </Window.InputBindings>
    <Grid>
        <CheckBox Content="myCheckbox" />
    </Grid>
</Window>

  public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            MessageBox.Show(e.Command.ToString());
        }

        private void CommandBinding_Executed_1(object sender, ExecutedRoutedEventArgs e)
        {
            MessageBox.Show("Will be closed now");
        }
    }

poniedziałek, 9 lipca 2012

[Wzorce projektowe] Command

Analogia z życia:

Gdy zepsuje nam się pralka dzwonimy po fachowca. Do jego zadań należy dojechać na miejsce, zlokalizować usterkę i naprawić urządzenie. Może się tak jednak zdarzyć, że w międzyczasie coś nam wypadnie i będziemy zmuszeni przesunąć wizytę. Wtedy również bierzemy telefon i informujemy fachowca o nowym terminie. W przypadku, gdy się rozmyślimy i postanowimy kupić nową pralkę, bierzemy telefon i odwołujemy wizytę.



Zastosowanie:


Zadaniem wzorca polecenia jest reprezentowanie akcji jako osobnego obiektu. Umożliwia to odseparowanie klienta, który tę akcję wywołuje od obiektu zajmującego się wywołaniem akcji wraz z jego zależnościami. Podejście takie umożliwia między innymi kolejkowanie akcji, walidację lub cofanie akcji już wykonanych. Z punktu widzenia klienta jest to wywoływanie pojedynczych metod, natomiast cała logika zakodowana zostaje w obiekcie reprezentującym akcję.

Zasada działania:

Komenda reprezentowana jest przez interfejs wystawiający proste, bezparametrowe metody typu wywołaj, waliduj, cofnij. Metody te są wołane przez klienta, gdy zachodzi taka potrzeba.

Przykład implementacyjny:

public interface ICommand
    {
        void Execute();
    }

    public class ExitCommand : ICommand
    {
        public void Execute()
        {
            Environment.Exit(0);
        }
    }

    public class ClearCommand : ICommand
    {
        public void Execute()
        {
            Console.Clear();
        }
    }

    public class AboutCommand : ICommand
    {
        public void Execute()
        {
            Console.WriteLine("This is sample program");
        }
    }

    public class NoSuchCommand : ICommand
    {
        public void Execute()
        {
            Console.WriteLine("Error - no such command");
        }
    }
  public class SimpleCommandFactory
    {
        private List<ICommand> _commands;

        public SimpleCommandFactory()
        {
            _commands = new List<ICommand>()
                            {
                                new AboutCommand(),
                                new ClearCommand(),
                                new ExitCommand()
                            };
        }

        public ICommand GetCommand(string name)
        {
            var cmd = _commands.FirstOrDefault(s => s.GetType().Name.Contains(name));
            if (cmd != null)
                return cmd;
            return new NoSuchCommand();
        }

        public void PrintAvailableCommands()
        {
            foreach (ICommand command in _commands)
            {
                Console.WriteLine(command.GetType().Name);
            }
        }
    }
 class Program
    {
        static void Main(string[] args)
        {
            var factory = new SimpleCommandFactory();
            Console.WriteLine("Available Commands Are :");
            factory.PrintAvailableCommands();
            while (true)
            {
                var arg = Console.ReadLine();
                var cmd = factory.GetCommand(arg);
                cmd.Execute();
            }
        }
    }