Alexey 的个人资料Life vs. Programming照片日志列表更多 工具 帮助

日志


5月31日

Команда, просто команда.

Давно ничего не писал - другие мысли в голове, но в за последние дни уже несколько раз сталкивался с различными странными способами решения одной и той же "проблемы".

"Проблема" эта состоит в следующем: необходимо динамически добавлять пользовательские элементы управления на форму. Естественно, эти элементы должны как-то реагировать на то, что делает с ними пользователь.
То есть, первоначально задача стоит так: у нас есть некая функциональность, которую должен активировать пользователь некими своими действиями, например, нажатиями на кнопки. Но первична именно функциональность, а не кнопки, кнопки -фигня, костыль, средство. Завтра кнопок может не стать, а появятся меню или голосовое управление или еще черти что.

Задача стара как мир, но каких только способов решения ее не увидишь... Сегодня, например, я даже столкнулся с таким совершенно экзотическим способом: разработчик наследовался от кнопки для того, чтобы определить ее поведение. То есть у него были такие наследники, как, скажем, SettingsButton, DeleteButton и т.д. Экземпляры этих кнопок создавались и передавались контролу, который их внутри себя размещал.

Сначала я не знал, смеяться мне или плакать, но потом решил, что, поскольку создавшего это я не знаю, то все же посмеюсь. Заодно и напишу о том, как эту задачу правильно решать. Ничего нового я не скажу и те, кто при слове "Команда" уже все поняли, дальше могут не читать.

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

public abstract class CommandBase
{
   
public abstract string Title { get; set; }
   
public abstract void Execute();
}


Потом мы просто создаем отдельный класс-команду для каждой ситуации, с разной логикой, разными параметрами конструктора и т.д. (UserDeleteCommand, StartGameCommand, etc).
Сделав это мы получим набор функциональности, которую обеспечивает наше приложение. Теперь давайте позволим пользователю воспользоваться этим набором.

Допустим, у нас есть контрол, в который динамически должны добавляться кнопки, нажимая на которые пользователь будет вызывать наши функции.
Для этого в контроле определим метод, скажем, такой:

private void RegisterButton(CommandBase command)
{
   
//Создадим пользовательский элемент, в данном случае - кнопку
   
Button btn = new Button();
    btn.Text = command.Title;

    //при нажатии на кнопку запускается команда
   
btn.Click += delegate(object sender, EventArgs e) { command.Execute(); };

    //добавим кнопку на панель кнопок
   
_buttonsPanel.Controls.Add(btn);
}

А потом просто использовать этот метод там, где мы "наполняем" пользовательский интерфейс:

MyProfileCommand

profileCmd = new MyProfileCommand(currentUser);
Navigator.RegisterButton(profileCmd);
MainMenu.RegisterMenu(profileCmd);

Создание пользовательского элемента на основании команды можно вынести в фабрику, в сервис или придумать что-то еще. Важно то, что мы не делаем в нашем коде микс из логики и элементов управления и то, что мы всегда можем использовать одну и ту же команду несколько раз, вызывая ее из разных элементов пользовательского интерфейса или из недр нашего приложения, поведение легко контроллируется, код легко поддерживается.

Здесь я привел наверное самый примитивный вариант использования этого простого подхода. Немного расширив его можно получить очень неплохой результат, но, прошу вас, не прибегайте в ваших приложениях ко всяческим экзотическим подходам в виде наследования кнопок, хранилища делегатов или писанине всей логики приложения в функциях типа button1_Click(..) :)
Подумайте, а вдруг этот код еще кому-то читать придется?!

评论

请稍候...
很抱歉,您输入的评论太长。请缩短您的评论。
您没有输入任何内容,请重试。
很抱歉,我们当前无法添加您的评论。请稍后重试。
若要添加评论,需要您的家长授予您相应权限。请求权限
您的家长禁用了评论功能。
很抱歉,我们当前无法删除您的评论。请稍后重试。
您已超过了一天之内允许提供的评论数上限。请在 24 小时后重试。
因为我们的系统表明您可能在向其他用户提供垃圾评论,您的帐户已禁用了评论功能。如果您认为我们错误地禁用了您的帐户,请联系 Windows Live 支持部门
完成下面的安全检查,您提供评论的过程才能完成。
您在安全检查中键入的字符必须与图片或音频中的字符一致。

若要添加评论,请使用您的 Windows Live ID 登录(如果您使用过 Hotmail、Messenger 或 Xbox LIVE,您就拥有 Windows Live ID)。登录


还没有 Windows Live ID 吗?请注册

引用通告

此日志的引用通告 URL 是:
http://patrol02.spaces.live.com/blog/cns!430EDF394C126296!650.trak
引用此项的网络日志