Использование директивы #if в сгенерированном дизайнером коде с Windows-формами для условной компиляции - PullRequest
0 голосов
/ 15 марта 2011

Фон :

У меня есть приложение C # Windows Forms, которое содержит службу Windows и интерфейс, используемый для настройки параметров системы, а также для связи со службой.

Желаемый результат :

Я хотел бы построить две версии решения - версию client со всеми кодами и элементами формы, связанными со службой Windows, и server версия, которая содержит все.

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

Проблема :

На этом этапе я использовал директивы #if для кода, связанного со службой Windows.Например:

#if SERVERBUILD
     //Code relating to Windows service that I do not want to compile 
     //for a client version.
#endif

В приведенном выше примере «SERVERBUILD» соответствует конфигурации сборки, которую я могу выбрать через Configuration Manager (в отличие от стандартной опции сборки «Release»).

Проблема, с которой я столкнулся, состоит в том, что часть кода, который мне пришлось обернуть вокруг этой директивы #if, находится в файле WinForm.Designer.cs в области с именем ' Код, сгенерированный конструктором форм Windows * '.

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

  • Правильно ли я поступаю?
  • Есть ли способ избежать ситуации, когда я теряю изменения, внесенные в WinForm.Designer.cs?code?

Буду очень признателен за любые советы от тех, кто имеет опыт работы с условной компиляцией и подобными вещами.

Ответы [ 3 ]

2 голосов
/ 15 марта 2011

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

Лучшим решением было бы идентифицировать весь общий код и хранить его в отдельной папке проекта, такой как common /.Тогда у вас есть конкретный код сервиса под сервером / например и все формы кода под клиентом /.

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

1 голос
/ 15 марта 2011
    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent() {

Нуфф сказал.Решите вашу проблему, поместив код в конструктор формы:

    public Form1() {
        InitializeComponent();
#if !SERVERBUILD
        panel1.Visible = false;
#endif
    }

Обратите внимание, что использование панели - это простой способ сделать все элементы управления на ней невидимыми.

1 голос
/ 15 марта 2011

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

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

...