valker's blog

valker's blog: идеи, размышления, наблюдения

Сопрограммы, паттерн "Команда", C#

leave a comment »

Иногда, при написании программы с оконным пользовательским интерфейсом, возникает необходимость реализовать некоторую логику открытия/закрытия окон. Эта ситуация усугубляется необходимостью передавать параметры между этими окнами. Сейчас я покажу, как я решил эту проблему.

В данном примере поочерёдно создаётся два окна: Form1 и Form2. У каждого из них 2 кнопки: Ok и Cancel. По нажатию Ok текущее окно закрывается и открывается следующее. По нажатию Cancel программы заканчивает выполнение.

Для начала, я создал два класса, производных от System.Windows.Forms.Form, и расположил на них по кнопки, определив для каждой свойство DialogResult.

Затем я добавил в проект вот такой интерфейс:

    2     interface ICommand {

    3         ICommand execute(ProgramContext host);

    4     }

Класс ProgramContext — для передачи параметров между окнами. В нашем тривиальном примере он пустой.

Затем я создал базовый класс реализующий этот интерфейс:

 

    4 internal class FormCommandBase : ICommand {

    5     protected delegate Form CreateFormDelegate();

    6 

    7     protected delegate ICommand CreateCommandDelegate();

    8 

    9     private CreateFormDelegate cf;

   10     private CreateCommandDelegate cd;

   11 

   12     protected FormCommandBase(CreateFormDelegate cf, CreateCommandDelegate cd) {

   13         this.cf = cf;

   14         this.cd = cd;

   15     }

   16 

   17     public ICommand execute(ProgramContext host) {

   18         Form f = cf();

   19         f.ShowDialog();

   20         ICommand returnValue = null;

   21         if (f.DialogResult == DialogResult.OK) {

   22             returnValue = cd();

   23         }

   24         return returnValue;

   25     }

   26 }

Как видно, основная работа сосредоточена в функции execute(), которая создаёт экземпляр формы, показывает его на экране, дожидается результата и, в случае положительного ответа, создаёт следующую команду.

Наследники этого класса пишутся просто:

 

    2 internal class FirstFormCommand : FormCommandBase {

    3     public FirstFormCommand() : base(

    4             delegate() {return new Form1();},

    5             delegate() {return new SecondFormCommand();})

    6     {}

    7 }

    2 internal class SecondFormCommand : FormCommandBase {

    3     public SecondFormCommand() : base(

    4             delegate() {return new Form2();},

    5             delegate() {return new FirstFormCommand();})

    6     {}

    7 }

Вот и всё, осталось нашу программу «склеить» и запустить:

 

    5 static class Program {

    6     /// <summary>

    7     /// The main entry point for the application.

    8     /// </summary>

    9     [STAThread]

   10     static void Main() {

   11         Application.EnableVisualStyles();

   12         Application.SetCompatibleTextRenderingDefault(false);

   13 

   14         ICommand cmd = new FirstFormCommand();

   15         ProgramContext context = new ProgramContext();

   16         while (cmd != null) {

   17             cmd = cmd.execute(context);

   18         }

   19     }

   20 }

Удачи вам на дорогах и весёлого программирования!

Ссылки:

Written by valker

Апрель 3, 2007 в 12:42 пп

Опубликовано в жизнь

Tagged with , , ,

Добавить комментарий

Please log in using one of these methods to post your comment:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: