Организация UI кодирует в формах.NET

Я - кто-то, кто преподавал мне программирование и не имел никакого формального обучения в программировании.NET.

Некоторое время назад я запустил C# для разработки программы GUI для управления датчиками, и проект цвел. Я просто задавался вопросом, как лучше всего организовать код, особенно код UI, в моих формах.

Мои формы в настоящее время являются путаницей или по крайней мере кажутся путаницей мне.

  • У меня есть конструктор, который инициализирует все параметры и создает события.
  • У меня есть гигантская государственная собственность, которая обновляет Включенный уровень всего моего контроля формой, в то время как пользователи прогрессируют через приложение (т.е.: разъединенный, соединенный, установка, сканируя) управляемый перечислением состояний.
  • У меня есть 3-10 частных переменных, к которым получают доступ через свойства, некоторые из которых имеют побочные эффекты в изменении значений элементов формы.
  • У меня есть много функций "UpdateXXX" для обработки элементов UI, которые зависят от других элементов UI - т.е.: если датчик изменяется, то измените выпадающий список скорости в бодах. Они разделены на регионы
  • У меня есть много событий, вызывающих эти функции Обновления
  • У меня есть второстепенный рабочий, который делает все сканирование и анализ.

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

Как Вы структурируете свои формы .NET?

Спасибо

11
задан AMissico 16 June 2010 в 09:58
поделиться

7 ответов

Вот ссылка на довольно часто используемый шаблон архитектуры.

http://en.wikipedia.org/wiki/Model_View_ViewModel

Я бы также поискал некоторые другие архитектурные шаблоны и подробнее изучил этот, поискал бы пример кода и т. Д.

0
ответ дан 3 December 2019 в 10:24
поделиться

Существует ряд паттернов, которые помогают разделить логику в приложениях, что приводит к созданию более чистого и удобного кода. Шаблон MVP - это хороший шаблон для начала. Он основан на определении трех областей ответственности, т.е. MVP M = модель, V = представление, P = ведущий. Если вы знакомы с использованием интерфейсов, у вас все получится, в противном случае это будет хорошим началом (ознакомьтесь с основными принципами ОО: инкапсуляция, абстракция, полиморфизм). Основной принцип MVP заключается в том, чтобы поместить логику приложения в презентатор. Презентер общается с представлением (вашей формой) через интерфейс, а представление обращается к презентеру (я использую интерфейс и для этого), когда пользователь взаимодействует с ним. Модель - это иерархия доменных объектов решения, которая имплицирует логику бизнеса и отношения между сущностями.

Большинство моделей пользовательского интерфейса (MVP, MCV и т.д.) пытаются делать одни и те же вещи, разделяя ваши проблемы. Ниже приведен простой пример:

//Интерфейс представления

interface IUserDetailsView
{

      string Username{set;get;}
      string FirstName{get;set;}
      string LastName{get;set;}
      UserDetailsPresenter Presenter{get;set;}
      void DisplayMessage(string message);


}

//Имплантация представления //Стандартная форма windows, которая имеет текстовые поля, метки, комбинации и т.д., которые

class UserDetailsView : Form, IUserDetails
{

      public string Username{set{txtUserName.text = value;}get{return txtUserName.text;}}
      public string FirstName{set{txtFirstName.text = value;}get{return txtFirstName.text;}}
      public string LastName{set{txtLastName.text = value;}get{return txtLastName.text;}}

      Public UserDetailsPresenter Presenter{get;set;}

      public void DisplayMaessage(string message)
      {
         MessageBox.Show(message);
      }

      private void saveButton_Click(object sender, EventArgs e)
      {
         Presenter.SaveUserDetails();

      }
}

//Логика представления

class Presenter UserDetailsPresenter {

  //Constructor
  public userDetailsPresenter(IUserDetailsView view)
  {
    //Hold a reference to the view interface and set the view's presnter
     _view = view;
     _view.Presenter = this;
  }

  private IUserDetailsView _view;

  DisplayUser(string userName)
  {
     //Get the user from some service ...
     UserDetails details = service.GetUser(userName);

     //Display the data vioa the interface
     _view.UserName = details.UserName;
     _view.FirstName = details.FirstName;
     _view.LastName = details.LastName;

  }

  public void SaveUserDetails()
  {

       //Get the user dryaiols from the view (i.e. the screen
       UserDetails details = new UserDetails();

       details.UserName = _view.UserName;
       details.FirstName = _view.FirstName;
       details.LastName = _view.LastName;

       //Apply some business logic here (via the model)
       if(!details.IsValidUserDetails())
       {
          _view.DisplayMessage("Some detail outlining the issues");
         return;
       }

       //Call out to some service to save the data
       service.UpdateUser(details);

  }

}

//И наконец, модель

public class UserDetails
{

   public UserName {get;set;}
   public FirstName{get;set;}
   public LastName{get;set;}

   public bool IsValidUserDetails()
   {
       if(LastName == "Smith")
       {
          //We do not allow smiths, remember what happened last time ... or whatever
          return false;
       }

       return true;
   }

}

Надеюсь, это объясняет, как разграничивается ответственность. Форма не имеет никакой логики, кроме отображения/форматирования и т.д., ее также можно заглушить для тестирования. Ведущий является посредником между представлением и моделью и делает вызовы к сервисам, а модель реализует вашу бизнес-логику. Как уже было сказано, существуют вариации этого паттерна, которые могут сделать ваш код немного более тонким и гибким, но здесь описаны основные принципы. Надеюсь, это поможет.

:-)

5
ответ дан 3 December 2019 в 10:24
поделиться

В сложных формах я обычно разделяю код на отдельные файлы. Это можно сделать с помощью "частичного класса". Каждый файл исходного кода имеет имя, основанное на форме. Например, MainForm.cs, MainForm.State.cs, MainForm.Update.cs, MainForm.Menu.cs и так далее. Если у меня много сложных форм, я создам подпапку для каждой. Единственный совет здесь - создать форму MainForm.Wip.cs. Эта форма частичного класса - код, над которым вы сейчас работаете. Как только вы закончите работу с этим кодом, вы можете либо переименовать его, либо переместить код в другие файлы исходного кода.

Кроме того, я также буду создавать пользовательские элементы управления. Это дает преимущество повторного использования кода и переносит большую часть функциональности за пределы формы. Посмотрите статью "Разработка пользовательских элементов управления Windows Forms с помощью .NET Framework" на http://msdn.microsoft.com/en-us/library/6hws6h2t.aspx.

Посмотрите Nobody Cares What Your Code Looks Like на http://www.codinghorror.com/blog/2007/12/nobody-cares-what-your-code-looks-like.html. Кое-что, о чем стоит подумать перед "организацией".

2
ответ дан 3 December 2019 в 10:24
поделиться

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

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

Вы даже можете создавать собственные элементы управления, которые не отображаются в форме, например, таймер.

0
ответ дан 3 December 2019 в 10:24
поделиться

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

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

0
ответ дан 3 December 2019 в 10:24
поделиться

Взгляните на паттерн "Модель-Вид-Презентатор": http://en.wikipedia.org/wiki/Model_View_Presenter

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

Суть в следующем: Ваши формы (представление) не должны содержать никакой информации о состоянии; она будет находиться в ведущем, и его не должно волновать, откуда он получает данные, до тех пор, пока эти данные соответствуют заданному контракту. Это повышает тестируемость, так как вы можете легко проверить ваши состояния и данные на презентере, и отделяет представление, позволяя использовать PLAFs, различные представления одних и тех же данных и тому подобное.

Удачи :)

1
ответ дан 3 December 2019 в 10:24
поделиться

Некоторые быстрые предложения:

Постарайтесь перенести весь ваш не пользовательский код из форм, вы хотите иметь только GUI код в реальной форме, если это возможно. Если свойство имеет побочный эффект, оно, вероятно, должно быть функцией. Ваше свойство State почти наверняка должно быть методом, и посмотрите, можете ли вы разбить код из него на отдельные методы, чтобы был только один вызов функции на состояние.

1
ответ дан 3 December 2019 в 10:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: