Поиск блогу

пятница, 7 октября 2011 г.

Создание связанных карточек

При создании сложной системы может потребоваться связывать карточки, т.е. сделать так, чтобы одна карточка, порождала другие, а при удалении главной карточки, карточки, связанные с ней удалялись тоже.
Например, создается карточка Проблемы (родительская), а к ней должна быть прикреплена карточка Решения (дочерняя).
Для этого необходимо следующее:
1. Создать в схеме данных карточки новое поле, которое будет представлять собой ссылку на карточку (refcardid) и в типе ссылки указать "Hard".


2. Положить на форму контрол карточки и привязать его к созданному полю (CardLink).

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

пятница, 9 сентября 2011 г.

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

понедельник, 8 августа 2011 г.

Рассылка уведомлений

В версии конструктора 4.5 есть сервис уведомлений.

С его помощью можно настроить рассылку уведомлений в виде ярлыка или почтового сообщения на изменения полей карточки. На данный момент уведомления рассылаются при изменении поля и последующем сохранении карточки. В связи с этим есть проблема, если необходимо отправить уведомление о смене состояния карточки. Для того, чтобы отправить такое уведомление, придется в скрипте карточки, меняющем ее состояние прописать принудительное изменение значения контрола состояния через PropertyController.UpdateProperty, либо (что будет оптимальнее при необходимости отправки нового состояния в уведомлении) записывать новое состояние в скрытый строковый контрол. Например, вот так:
 CardData cStates = Session.CardManager.GetCardData(new Guid("{7984F2CE-9345-4C59-B66B-7125DD9195A1}"));// Получаем справочник ролевой модели. В нем хранятся состояния
 PropertyController.UpdateProperty("СтрокаСостояния",cStates.Sections[new Guid("{521B4477-DD10-4F57-A453-09C70ADB7799}")].Rows[DomainObject.StateId].GetString("DefaultName"));// Получаем название текущего состояния и записываем его в контрол.

четверг, 21 июля 2011 г.

Изменение вида карточки

Предположим, что на карточке лежит контрол "Вид".
Опытным путем я установил, что при изменении значения в нем, само изменение вида карточки происходит уже после события ControlValueChanged.

Это означает то, что при написании ControlValueChanged для этого контрола нужно использовать PropertyController.GetPropertyValue("НазваниеКонтролаВида") вместо DomainObject.KindId, чтобы получить в скрипте новое значение вида.

вторник, 12 июля 2011 г.

Скрипт на привязку карточки с табличному контролу.

Всем привет :-)
В одну из составляющих моей разработки решения"Управление совещаниями", входит объединение всех трёх карточек в единую работающую систему. Для этого мне требуется написать несколько скриптов на событие AddButtonClick табличного контрола. Мои познания в ООП находятся на уровне основных понятий, поэтому самостоятельно выполнить поставленную задачу будет крайне трудно, и если уважаемые разработчики помогут мне с преодолением этой проблемы, я буду им очень благодарен за проявленное содействие в достижении личных и организационных успехов.

Итак, задача:
В основной карточке "Совещание" ( Card 1 ) в таблице с вопросами повестки, при нажатии на добавить "+", должна появляться новая карточка "Вопросы повестки" ( Card 2 ). Так же, при каждом нажатии на добавить "+" карточка должна обновляться.




Был использован метод:
{
object newCard = Session.CardManager.CreateCard(new Guid("{5763AAF2-BF9B-4373-AF1B-6360EF4A2FFA}"));
}
но при загрузке карточки он выдаёт ошибку, что "Данный метод не поддерживается".

Вопрос : Какой скрипт будет выполнять поставленную задачу?

Спасибо)

четверг, 30 июня 2011 г.

Как подключать сборки в конструкторе DocsVision

Рано или поздно придется столкнуться с подключением сборок в конструкторе.

Находятся все сборки по пути Windows/assembly/GAC_MSIL

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

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

Из-за особенностей Конструтора у вас не получится подключить сборки сразу из assembly, поэтому скопируйте сначала нужные сборки в отдельную папку и уже оттуда подключайте. Но лучше удалить из GAC_MSIL скрытый файл "Desktop.ini". После этого папки со сборками станут видны из конструктора и их не придется никуда копировать. Также одном из плюсов данного способа является тот факт, что при переносе решения на другую машину, вам не придется заново прописывать пути к сборкам.

Для подключения сборки кликните на "+" в нижней таблице "Используемые дополнительные сборки" в окне редактирования скриптов конструктора, выберите нужную сборку и добавьте ее в таблицу.

Получение данных выделенной строки из таблицы

Вывод выделенной строки оказался весьма нетривиальным заданием.

Данный фрагмент кода выведет в MessageBox содержимое выделенной строки в табличном контроле с названием "Журнал заявки".

LayoutHelper layoutHelper = new LayoutHelper(CardControl.LayoutControl, CardControl.BarManager, Session, CardData.Type.Id);
DocsVision.BackOffice.View.WinForms.LayoutItems.ICustomPropertyItem propertyItem = layoutHelper.GetCustomPropertyItem("Журнал заявки");
var refMapper = new CardPropertyDescriptionMapper(Session);
DocsVision.BackOffice.Model.CardProperties.Entities.CardPropertyTable cpt = null;
foreach (DocsVision.BackOffice.Model.Layouts.Entities.CardPropertyTableDescription refPropertyTableDesc in refMapper.FindTableProperties(CardData.Type.Id))
          {
              if (refPropertyTableDesc.Name == "Журнал заявки")
               {
                 var propertyMapper = new CardPropertyMapper(Session, CardData.Id, DomainObject.CustomPropertiesSectionId);
                   cpt = propertyMapper.FindTable(refPropertyTableDesc);
                   break;
               }
          }
System.Reflection.Assembly asm = System.Reflection.Assembly.Load("DocsVision.BackOffice.View, Version=4.5.0.0, Culture=neutral, PublicKeyToken=7148afe997f90519");
Type tableType = asm.GetType("DocsVision.BackOffice.View.WinForms.PropertyControls.TablePropertyControl");
var propInfo = tableType.GetProperty("GridView");
object ooo = propInfo.GetValue(propertyItem.Control, System.Reflection.BindingFlags.NonPublic, null, null, System.Globalization.CultureInfo.InvariantCulture);
DocsVision.BackOffice.View.WinForms.Controls.GridExView gridExView = ooo as DocsVision.BackOffice.View.WinForms.Controls.GridExView;
DevExpress.XtraGrid.Views.Grid.GridView gridView = gridExView as DevExpress.XtraGrid.Views.Grid.GridView;
object key = ((System.Data.DataRowView)gridView.GetFocusedRow()).Row[gridExView.KeyField];
          foreach (DocsVision.BackOffice.Model.CardProperties.Entities.CardPropertyTableRow row in cpt.Rows)
          {
              if (row.Key == (Guid)key)
              {
                  string message = "";                  
                  foreach (DocsVision.BackOffice.Model.CardProperties.Entities.CardProperty cellProp in row.Cells)
                      {
                       object val = cellProp.Value;                          
                       message += val == null ? "null" : val.ToString();
                       message += " ";    
                      }
                      MessageBox.Show(message);
                      }
    
              }


Для работы скрипта нужно прописать в using:

using DocsVision.Platform.WinForms.DataSource;
using DocsVision.BackOffice.Model.CardProperties.DataAccess;


Возможно, что-то еще...

а также подключить сборки DevExpress. А именно
DevExpress.XtraLayout.9.2.dll
DevExpress.XtraGrid.9.2.dll
DevExpress.Data.9.2.dll
DevExpress.Utils.9.2.dll

Добавление новой строки в табличный контрол из скрипта

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

Рассмотрим на примере таблицы, содержащей 3 столбца: Дату, идентификатор сотрудника и некоторый текст.

в приведенном скрипте:
secComment - это идентификатор табличной секции(Guid);
comment - какая-то строка(string)

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

Guid g = Guid.NewGuid();
CardData.Sections[secComment].BeginUpdate();
RowData newComment = CardData.Sections[secComment].CreateRow(g);
newComment.SetString("Текст", comment);
newComment.SetGuid("Автор", new EmployeeMapper(Session).GetCurrentUserId());
newComment.SetDateTime("Дата", DateTime.Now);
CardData.Sections[secComment].EndUpdate();

суббота, 21 мая 2011 г.

Смена атрибутов контрола из скрипта. На примере атрибута ReadOnly

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

using System;
using System.Windows.Forms;
using DocsVision.Platform.ObjectManager;
using DocsVision.BackOffice.View.WinForms;
using DocsVision.BackOffice.Model;
using DocsVision.BackOffice.Model.Layouts.DataAccess;
using DocsVision.BackOffice.Model.Base.Entities;
using DocsVision.BackOffice.Model.CardProperties.Entities;
using DocsVision.BackOffice.Model.Layouts.Entities;
using DocsVision.BackOffice.Model.RoleModel.DataAccess;
using DocsVision.BackOffice.Model.RoleModel.Entities;
using DocsVision.BackOffice.View.WinForms.Helpers;

private void cardControl_AfterActivate(System.Object sender, System.EventArgs e)
    {
  CardProperty prop = GetCardProperty("имя контрола");
  CardPropertyDescription.LayoutAttributeSet attrSet = prop.Description.GetLayoutAttributes(CardControl.DomainObject.SelectedLayoutId);
        attrSet.ReadOnly = true;
        PropertyController.Refresh();
    }

//Поиск контрола с нужным именем  
private CardProperty GetCardProperty(string propertyName)
 {
 foreach (CardProperty property in PropertyController.CardProperties)
  {
  if (property.Name == propertyName)
  return property;
  }
 return null;
 }

среда, 11 мая 2011 г.

Перезапуск сервисов из командной строки

Думаю, что многие сталкивались с проблемой, что какие-то изменения, внесенные в структуру DV требовали перезапуска серверов, SQL и IIS. На это уходит много времени, так как надо полазать по различным административным менюшкам и покликать много кнопок.

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

1. создаем новый текстовый файл.
2. в тело пишем

NET stop DVStorageServer45
NET stop WFServer45
NET stop MSSQL$SQLEXPRESS
IISReset
NET start MSSQL$SQLEXPRESS
NET start DVStorageServer45
NET start WFServer45


3. сохраняем файл на рабочий стол под именем Reset.bat и в свойствах файла выставляем "Запускать от имени Администратора". Иногда для этого приходится создать ярлык на этот батник и в его свойствах поставить запуск от имени администратора.
4. наслаждаемся перезапуском в один клик.

P.S. Возможно, что SQL сервер у вас называется не SQLEXPRESS. В таком случае либо просто удалите из батника строку перезапуска SQL (Обычно такой перезапуск не требуется), либо впишите свое название сервера.