5 место Перенос WinForms из VisualStudio в ZennoPoster

radv

Client
Регистрация
11.05.2015
Сообщения
3 673
Благодарностей
1 855
Баллы
113
Всем привет, в этой статье, я опишу суть как можно формы (WinForms) созданные в VisualStudio адаптировать под работу в проектах ZennoPoster.

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

Весь процесс будет через C#. Это моя первая конкурсная статья (участие в конкурсе шаблоном, я в расчет не принимаю), и в изучении C# я только оттачиваю свои навыки поэтому прошу принять это во внимание. Если Ваш уровень выше моего, и что то можно было сделать более оптимально буду рад Вашим комментариям.

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

Итак, начинаем. Все формы в проектах VisualStudio записываются в три файла. В именах этих файлов содержится название формы.

Например: если форма называется FormForZenno, тогда в файле FormForZenno.cs будет код действий для этой формы при загрузке формы, нажатии на кнопки, выборе значений элементов и т.п., в файле FormForZenno.Designer.cs содержится код дизайна формы (все ее элементы и компоненты) и в файле FormForZenno.resx содержатся все значения для дизайна формы. Вот эти файлы и нужны для работы, скопируем их содержимое в переменные проекта ZennoPoster.

01 файлы.png


Перенесем код из этих файлов в строковые переменные проекта Zennoposter.

В переменной strCodeActions будет код действий из файла FormForZenno.cs

В переменной strFormDesign будет код дизайна формы из файла FormForZenno.Designer.cs

В переменной strRESX будет код с ресурсами из файла FormForZenno.resx

Шаг 1: Обработка действий

В первую очередь обработаем код действий из файла FormForZenno.cs. Для того чтобы адаптировать код нужно для всех действий при клике заменить все "_Click" на ".Click+=delegate" или для действий при загрузке формы заменить "_Load" на ".Load+=delegate".

Если в форме не используются действия (ни при загрузке формы, ни нажатия на кнопки и т.п.), этот шаг можно пропустить

Вот код этой обработки для кубика C#

C#:
// Паттерн регулярки для поиска

string strPattern = @"(?<=\ ).*?_Click";

// Цикл добавления комментария перед каждым действием на клик

foreach (Match rxMatch in Regex.Matches(strCodeActions, strPattern)) {

  // ищем  private void и т.п. для удаления перед _Click

  strPattern = @"\ .*\ ";

  //= Берем первое совпадение с регуляркой

  string strTempForReplace = new Regex(strPattern).Match(rxMatch.Value).Value.Trim();

  // Комментарий с уникальными символами, для вставки перед кодом действия

  string strHashTag= "//@@"";

  //Все совпадения

  strCodeActions = strCodeActions.Replace(strTempForReplace, strHashTag);

  project.Variables["sourceForm"].Value = strCodeActions;

}

// Для действий при клике

strCodeActions = strCodeActions.Replace("_Click", ".Click+=delegate");

// Для действий при загрузке формы

strCodeActions = strCodeActions.Replace("_Load", ".Load+=delegate");
После выполнения этого кода, каждый блок кода действий будет разделен комментарием уникальными символами, которые нигде в коде не могут встречаться. В данном случае, я взял символы "//@@". Такой же комментарий нужно добавить в конец переменной с кодом действий, тогда по регулярке можно будет выдергивать блок кода для нужного компонента (например кнопки) и вставлять в нужное место файла результата после обработки файлов с дизайном и ресурсами.

Работа с обработкой файла действий, завершена(к нему вернемся при сборке в итоговый файл с результатом). Переходим к обработке с файлом дизайна формы.


Шаг 2: Обработка файла с дизайном формы

При обработке файла FormForZenno.Designer.cs нужно получить названия всех компонентов, а так же сделать их инициализацию и подключение к форме. Название формы можно задать вручную (или получением из кода)

C#:
// Создаем список куда записываем результат обработки

List<string> lstResult = new List<string>();

// Название формы FormName

string strFormName = "FormForZenno";

//потом формируем строку для Инициализации формы

string strInit = String.Format("System.Windows.Forms.Form {0} = new System.Windows.Forms.Form();", strFormName);

// Записываем ее в список

lstResult.Add(strInit);

В коде с дизайном ищем все компоненты и разделяем их на Имя компонента и его Класс для правильной инициализации в коде кубика C#

так строка strInit для формы будет иметь значение "System.Windows.Forms.Form FormForZenno = new System.Windows.Forms.Form(); что создаст новую форму без ошибок.

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

02 код формы.png


Между #region и #endregion код всех компонентов формы, который нужно будет обработать.

Код обработки сбора названия и классов компонентов формы в список

C#:
// Блок список компонентов в без параметров формы

strPattern = @"(?<=InitializeComponent)[\w\W]*?(?=//)";

//= Берем первое совпадение с регуляркой (все блоки с параметрами компонентов)

string strListComp = new Regex(strPattern).Match(strFormDesign).Value.Trim();

// Регулярка список компонентов в правильном порядке

strPattern = @"(?<=this\.).*?;";

// Создадим список компонентов

List<string> listCompName = new List<string>();

listCompName.Clear();

// части CompClassName и CompName

string strCompClassName = String.Empty;

string strCompName = String.Empty;

// Ищем все совпадения для сохранения в список компонентов

foreach (Match rxMatch in Regex.Matches(strListComp, strPattern)) {

  // удаляем все this, если они остались

  string strTemp = rxMatch.Value.Trim().Replace("this.", String.Empty);

  // Разделяем на Имя компонента и Класс

  string[] arrTemp = strTemp.Split('=');

  if (arrTemp.Length > 1) {

  // Все совпадения кладем в список

  strCompName = arrTemp[0].Trim();

  strCompClassName = arrTemp[1].Trim();

  string strTempPattern = @"(?<=\ System\.Windows\.Forms\.).*?(?=\()";

  //= Берем первое совпадение с регуляркой (все блоки с параметрами компонентов)

  strCompClassName = new Regex(strTempPattern).Match(strCompClassName).Value.Trim();

      if (strCompClassName != String.Empty) {

          strTemp = strCompClassName + "|" + strCompName;

         listCompName.Add(strTemp);

      }

  }

}

// Добавляем название формы для сбора ее параметров

listCompName.Add(String.Format(@"Form|{0}", strFormName));
После выполнения этого кода получаем список компонентов формы для которых будем собирать их параметры. Список будет вида textBox1|TextBox (Название компонента и его Класса через разделитель | (вертикальная черта) )


Параметры компонентов и самой формы разделены на блоки с названием компонента в комментарии.

04 параметры компонета.png


Параметры самой формы задаются после параметров всех компонентов.

04 параметры формы.png


Далее в цикле перебираем все компоненты по их именам из списка listCompName и в список listCompParam собираем все блоки с параметрами каждого компонента

Код обработки

C#:
// Регулярка Вырезаем блок с параметрами всех компонентов формы

strPattern = @"(?<=InitializeComponent)[\w\W]*(?=\#endregion)";

//= Берем первое совпадение с регуляркой (все блоки с прараметрами компонентов)

string strListParamComp = new Regex(strPattern).Match(strFormDesign).Value.Trim();

// Удаляем все this.

strListParamComp = strListParamComp.Replace("this.", String.Empty).Trim();

// Создадим список

List<string> listCompParam = new List<string>();

listCompParam.Clear();

while (listCompName.Count > 0) {

  //Берем из списка ListCompName первую строку с удалением

  string[] arrTemp = listCompName[0].Split('|');

  listCompName.RemoveAt(0);

  //Разделяем на части CompClassName и CompName

  strCompClassName = arrTemp[0];

  strCompName = arrTemp[1];

  if (strCompClassName != "Form") {// Пропускаем формирование инициализации формы (сделали его раньше)

  //формируем строки для Инициализации компонента из списка

  strInit = String.Format("System.Windows.Forms.{0} {1} = new System.Windows.Forms.{0}();", strCompClassName, strCompName);

  // Записываем в список

  lstResult.Add(strInit);

  }

  // Название след. компонента

  string strCompNameNext = String.Empty;

  if (listCompName.Count > 0) {

  //Берем из списка ListCompName первую строку с удалением

  arrTemp = listCompName[0].Split('|');

  //Разделяем на части CompClassNameNext и CompNameNext

  //CompClassNameNext = arrTemp[0];

  strCompNameNext = arrTemp[1];

  } else {

  // когда все названия компонентов закончились, собираем параметры для формы

  strCompNameNext = String.Empty;

  }

  // Разделяем на блоки отдельных компонентов между strCompName и strCompNameNext

  if (strCompName == strFormName){

  strPattern = String.Format(@"(?<=//\ {0})[\w\W]*", strCompName);

  } else {

  strPattern = String.Format(@"(?<=//\ {0})[\w\W]*?(?=//\ {1})", strCompName, strCompNameNext);

  }

  // Вырезаем параметры компонента CompName {1} в CompNameNext {3}

  string strCodeParamComp = new Regex(strPattern).Match(strListParamComp).Value.Trim();



  // удаляем лишние символы // по краям

  strCodeParamComp = strCodeParamComp.Replace("//", String.Empty).Trim();

  // задаем временную переменную для обработки параметров

  string strTemp = String.Empty;

  string strParamCompName = String.Empty;

  // Выбираем строку отдельного параметра компонента от начала строки до ;

  strPattern = @"([\w\W]*?;)";

  // Для перебора всеx параметров у этого компонента

  foreach (Match rxMatch in Regex.Matches(strCodeParamComp, strPattern)) {

  strTemp = rxMatch.Value.Trim();

  // Код цикла перебора значений для каждого компонента (будет описан ниже)

   }

}// закончили перебор всеx компонентов из списка listCompName
В итоге получили список с параметрами для каждого компонента.

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

Действия при клике выглядят так

05 действия при клике.png


Если есть ресурсы (в параметре содержится resources.ApplyResources или просто resources) делаем их обработку кода из переменной strRESX (код из файла FormForZenno.resx). Если форма простая, то значения в ресурсы могут и не записываться, все значения будут в параметрах компонента и их обработка не потребуется.

Код обработки если есть действие при клике

C#:
// Регулярка выбора кода действия для компонента по разделителю strHashTag (уникальные символы которые мы задали “//@@”

strPattern = String.Format(@"{0}[\w\W]*?(?={1})", strCompName, strHashTagComment);

//= Берем первое совпадение с регуляркой (все блоки с параметрами компонентов)

string strClickAction = new Regex(strPattern).Match(strCodeActions).Value.Trim();

// Комментарий для кода в файле

//разделитель элементов списка

string strDelimiter = Environment.NewLine;

strComment = String.Format("{1}// Действие при клике для {0} {1}// Проверьте синтаксис и количество закрывающих скобок  и ; {1}", strCompName, strDelimiter);

// Записываем в список

listCompParam.Add(strComment);

// Код действий при клике

strClickAction = strClickAction.Replace("DialogResult", "System.Windows.Forms.DialogResult") + ";" + strDelimiter;

// Добавляем название формы

strClickAction = strClickAction.Replace(@"Close()", String.Format(@"{0}.Close()", strFormName));

listCompParam.Add(strClickAction);
Таким образом получили код нужного действия

Для обработки действий при загрузке формы и остальных параметров (без использования ресурсов) используем такой код обработки

C#:
//Обработка параметров формы и остальных параметров компонентов без ресурсов записываем в список параметров

if (strCompName == strFormName) {

  if (!strTemp.Contains("Layout") && !strTemp.Contains("Init")){

  // Для параметров формы

  if (strTemp.Contains("+=")){

  // Для действий при загрузке формы

  string strFormAction = new Regex(@"(?<=\().*(?=\))").Match(strTemp).Value.Trim();

  strFormAction = strFormAction.Replace("_",".");

   // Регулярка выбора кода действия для компонента

  strPattern = String.Format(@"{0}[\w\W]*?(?={1})", strFormAction, strHashTagComment);

  //= Берем первое совпадение с регуляркой (все блоки с прараметрами компонентов)

   string strClickAction = new Regex(strPattern).Match(strCodeActions).Value.Trim();

  // Комментарий для кода в файле

  strComment = String.Format("{1}// Действие при клике для {0} {1}// Проверьте синтаксис и количество закрывающих скобок и ; {1}", strFormAction, strDelimiter);

  // Код действий при клике

  strClickAction = strClickAction.Replace("DialogResult", "System.Windows.Forms.DialogResult") + ";" + strDelimiter;

  // Формируем нужный код

  strTemp = strComment + strClickAction;

  } else {

  strTemp = strFormName + "." + strTemp;

  }

  } else if (strTemp.Contains("Init")) {

  // Для остальных параметров

  strTemp = "// Пропуск параметра System.ComponentModel.ISupportInitialize";

  }

}

listCompParam.Add(strTemp);
Таким кодом мы вместо строки с действием вставляем сам код действия адаптированный под выполнение в ZennoPoster и комментарий проверки синтаксиса и лишних символов.

После цикла обработки всех параметров осталось все собрать в файл результатов и сохранить в файл

C#:
// Переносим собранные параметры в список

lstResult.AddRange(listCompParam);

// Параметры для формы

strComment = strDelimiter + String.Format(@"// Добавьте {0}. к ResumeLayout и PerformLayout выше этого сообщения", strFormName);

lstResult.Add(strComment);

// Параметры для Диалога по умолчанию

//strComment = strDelimiter + String.Format(@"Добавьте {0}. к ResumeLayout и PerformLayout выше этого сообщения", strFormName);

//lstResult.Add(strComment);

// Параметры для формы по умолчанию

strComment = strDelimiter

  + "// Закомментируйте параметры формы по умолчанию, если они заданы в ее настройках"

  + strDelimiter

  + "// Название формы по умолчанию"

  + strDelimiter

  + String.Format(@"{0}.Text = ""Название Формы"";", strFormName)

  + strDelimiter

  + "// АвтоРазмер формы по умолчанию"

  + strDelimiter

  + String.Format(@"{0}.AutoSize =  true;", strFormName)

  + strDelimiter

  + "// Местоположение формы по умолчанию"

  + strDelimiter

  + String.Format(@"{0}.Location = new System.Drawing.Point(150,300);", strFormName)

  + strDelimiter

  + "// Запуск формы по центру экрана"

  + strDelimiter

  + String.Format(@"{0}.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;", strFormName)

  + strDelimiter

  + "// Размер формы по умолчанию"

  + strDelimiter

  + String.Format(@"{0}.Size = new System.Drawing.Size(300, 180);", strFormName)

  + strDelimiter;

lstResult.Add(strComment);

// Показываем эту форму

strComment = strDelimiter

  + "// Показываем нашу форму "

  + strDelimiter

  + String.Format(@"{0}.ShowDialog();", strFormName);

lstResult.Add(strComment);

//сохраняем список в файл с заменой содержимого файла (после сбора всех данных в список)

File.WriteAllText(strFilePathReslt, String.Join(strDelimiter, lstResult));

project.SendInfoToLog(String.Format(@"Все готово.  Результат в файле {0}", strFilePathReslt)

);
В итоге получаем файл с результатами и комментариями. Код из этого файла можно вставить в кубик C# и проверить работу нашей формы.

Шаг 3: Финальные правки

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

Привожу два комментария на которые надо обратить внимание:

C#:
// Проверьте синтаксис и количество закрывающих скобок  и ;

// Добавьте FormForZenno. к ResumeLayout и PerformLayout выше этого сообщения
Просто делаете что написано в таких комментариях и все готово, форма работает.

Подробности смотрите в видео к этой статье.

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

В статье была пропущена обработка ресурсов, на это потребуется больше времени. Это будет доступно в полной (возможно платной) версии шаблона, или код обработки ресурсов можете сделать своими силами, применяя знания на практике.
 
Тема статьи
Нестандартные хаки
Номер конкурса статей
Девятый конкурс статей

Вложения

Для запуска проектов требуется программа ZennoPoster или ZennoDroid.
Это основное приложение, предназначенное для выполнения автоматизированных шаблонов действий (ботов).
Подробнее...

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

Последнее редактирование:

iBotovod

Client
Регистрация
01.07.2017
Сообщения
56
Благодарностей
19
Баллы
8
канонiчные тру-програмеры молча, без тарахтения в каментах, голосуют, качают шаб и идут дальше :-)
и в этой статье чувствуется "тлетворное" влияние Сиборры )
спасибо за любопытную тему
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 673
Благодарностей
1 855
Баллы
113

Moadip

Client
Регистрация
26.09.2015
Сообщения
509
Благодарностей
823
Баллы
93
Предлагаю как дополнение, ну или в виде отдельной статьи, написать как использовать wpf в зенке.
Формы на winforms это конечно хорошо, но что то глобальное будет проблематично сделать. Плюс на wpf можно гораздо красивее UI сделать, или то что на winforms нереально.
Проблема только в том, что при использовании wpf UI делают через xaml, можно конечно и через обычный C#, но это будет то еще извращение.
В общем просто так xaml не запихать в зенку.))
Я делал что UI в виде отдельной либы, чисто один интерфейс, потом подключал к шабу в зенке, и уже связывал контролы в интерфейсе с кодом в самой зенке.
Думаю народу такую инфу будет интересно почитать, ну даже так, для общего развития.))

В статье была пропущена обработка ресурсов, на это потребуется больше времени.
@radv напиши что вообще подразумевается под "ресурсами", т.к. кто не в теме, тот вообще не поймет что это и нахрена.
Ну и так, на заметку, смысл заморачиваться с обработкой ресурсов, если эти "ресурсы" можно напрямую добавить в зенку?
Другими словами, мы сначала создали себе проблему, напихали "ресурсов" в resx, а потом решаем ее.:-)

Это будет доступно в полной (возможно платной) версии шаблона
Маркетинг он такой маркетинг.:D

В целом посмотрел подход, шабы не качал. Как то все сложно. Конечно хз, на вкус и цвет все фломастеры разные.:-)

По факту надо перенести то что нагенерил дизайнер VS в зенку, ну и плюс привязать какую то логику.

Делал так.
В OwnCode делается класс, ну типа SomeClass1, в нем метод Loader(), он собственно создает форму и добавляет в нее все компоненты, плюс подключает обработчики к контролам.
В этом же классе идут методы обработчики для кнопок или еще каких контролов на форме.
Все.

Создали объект класса SomeClass1, вызвали метод Loader(), он нам возвращает форму, показали эту форму, что то сделали. Если замысел был что "в обратку" получается какая то инфа, добавили или свойства в класс SomeClass1, или методы, которые возвращают нужную инфу.

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

radv

Client
Регистрация
11.05.2015
Сообщения
3 673
Благодарностей
1 855
Баллы
113
написать как использовать wpf в зенке.
Формы на winforms это конечно хорошо, но что то глобальное будет проблематично сделать. Плюс на wpf можно гораздо красивее UI сделать, или то что на winforms нереально.
С WPF пока совсем не разбирался, а вот с дополнительными библиотеками на WinForms можно сделать очень даже красивые формы или интерфейсы, вплоть до ленты с кнопочками и вкладками как в MSOfifce или Зенке

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

В целом посмотрел подход, шабы не качал. Как то все сложно. Конечно хз, на вкус и цвет все фломастеры разные.:-)

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

Чтобы в коде совсем не копаться, если кто то не очень его понимает, или совсем не понимает. все будет автоматом делаться. Нагенерил форму в VS, запустил шаб, получил код, вставил и все готово к использованию :-)

Насчет остальных предложений и дополнений, как наберусь опыта, то поделюсь в отдельной статье или другим способом.
 
Последнее редактирование:

Moadip

Client
Регистрация
26.09.2015
Сообщения
509
Благодарностей
823
Баллы
93
очень даже красивые формы или интерфейсы, вплоть до ленты с кнопочками и вкладками как в MSOfifce или Зенке
В курсе.

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

Карочь не удержался, скачал. Посмотрел.
Ок, способ имеет место быть, по сути делает то о чем и писал, соединяет код дизайнера и свой код, разница в том что предлагается добавить код не в owncode, а в кубик C# сразу. С этим бы поспорил.
Вопрос. Не спотыкнутся ли регулярки если будут вложенные классы или еще что?
А если несколько форм, что делать? Или если в "нашем" коде используем доп. классы которые сами сделали, что с ними делать?
Я как бы не докапываюсь, а так, уточняю.:-)

и не надо ничего мудрить
Мудрить, это как раз обрабатывать cs регулярками.
Надо работать с кодом напрямую, без понимания того что делается рано или поздно возникнут вопросы. Что то не так спарсится, и код не будет компилиться в зенке.
Еще раз повторюсь, способ имеет место быть. Как вариант для понимания что переносить из студии и как.
Т.е. смотрим что в студии, смотрим что получилось на выходе, разбираем в чем разница.
Но имхо, проще сделать копипаст из студии в зенку, и подправить что надо.

PS:
Предлагаю сделать upgrade.
upload_2018-5-14_16-40-13.png

Выбирать файлы ручками лениво. Лучше указываешь путь до папки проекта, а остальное пусть все шаб делает.
 
Последнее редактирование:
  • Спасибо
Реакции: Yuriy Zymlex и LaGir

radv

Client
Регистрация
11.05.2015
Сообщения
3 673
Благодарностей
1 855
Баллы
113
Вопрос. Не спотыкнутся ли регулярки если будут вложенные классы или еще что?
А если несколько форм, что делать? Или если в "нашем" коде используем доп. классы которые сами сделали, что с ними делать?
Насколько я понял на данный момент, простые формы обрабатывает нормально, со вложенными классами надо пробовать на конкретном примере, пока не встречался с такими. Если имеешь виду родительские элементы у компонентов, например панель, а на нее складываются label, textbox и т.п. , то все это складывается в ресурсы и можно обработать. Регулярки не должны спотыкаться, так как там все однотипно и на сложные конструкции идет ссылка на файл с ресурсами, а в нем для конкретного элемента задаются нужные параметры.

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

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

Но имхо, проще сделать копипаст из студии в зенку, и подправить что надо.
Я пробовал так, не работает. Поэтому и заморочился над таким шаблоном, так как править приходилось ручками и много


Предлагаю сделать upgrade.
Выбирать файлы ручками лениво. Лучше указываешь путь до папки проекта, а остальное пусть все шаб делает.
а ручками код править после копипаста не лениво? :-) Сейчас по умолчанию открывает папку проекта и если скопировать туда нужные файлы, то так надежнее, можно конечно и прописать обработку файлов в папке, но можно файлы в папку не копировать, а просто выбирать их из папки проекта VS. И как бы лень не было, а кнопочку на выполнение шаба, все равно придется нажать :-)
 
Последнее редактирование:

ssXXXss

Client
Регистрация
23.12.2014
Сообщения
7 379
Благодарностей
2 039
Баллы
113
не замечал такого чтобы там много чего то править, в общем коде всё принимается нормально покрайней мере если с формой работать
 

radv

Client
Регистрация
11.05.2015
Сообщения
3 673
Благодарностей
1 855
Баллы
113
Если ошибок в коде нет, то можно и в общий код вставить. в кубик вставлял для проверки на ошибки
 

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)