Взаимодействие нескольких Add Ins

Наверное,В РјРЅРѕРіРёРµ РёР· нас имели определенные сложности РІ работе СЃ RTC после продолжительного использования классического клиента. Р’СЃРµ-таки новый интерфейс, сочетание горячих клавиш… Р? это вполне нормальный рабочий процесс.

Лично у меня до сих пор большие проблемы в привыкании возникают с уже упомянутыми горячими клавишами и работе с некоторыми карточными формами. Возьмем, к примеру, заказ продажи в RTC: выбор товара в строках заказа несколько изменился по сравнению с классическим клиентом.

Возможно, было Р±С‹ полезно иметь некий инструмент, позволяющий быстро перекидывать РІ строки заказа различные товары без использования лукапа РІ поле “РќРѕ.”. Например, форма заказа продажи могла Р±С‹ иметь следующий РІРёРґ:

12.png

В 

РќР° правой панели расположен Add In, позволяющий, выделив строку любого товара, перетащить его РІ поле Bin (The bin for items) - второй Add-in, способный распознавать пришедший товар. Причем процесс перетаскивания товара должен сопровождаться соответствующей подсказкой пользователю (РїРѕРєР° товар находится “между” правой панелью Рё “РєРѕСЂР·РёРЅРѕР№”, должен отображаться перечеркнутый РєСЂСѓРі; Р° РІ момент достижения “РєРѕСЂР·РёРЅС‹” должен появляться стандартный значок вставки). Более того, если пользователь, перетаскивая товар РёР· правой панели, отпустит левую РєРЅРѕРїРєСѓ мыши, товар РЅРµ должен попасть РІ строки заказа. Если же левая РєРЅРѕРїРєР° мыши была отпущена РІ “РєРѕСЂР·РёРЅРµ” - должна создаваться строка заказа продажи.

Соазу РѕРіРѕРІРѕСЂСЋСЃСЊ, что РЅРµ СЃРјРѕРіСѓ показать РЅР° картинках процесс “перетаскивания”: РЅР° принтскрине это действие РЅРµ отобразится. РќРѕ ниже приведу полный листинг РєРѕРґР°. Так что повторить Рё убедиться РІ правдивости сможет любой желающий.

Р?так, создадим библиотеку, РІ которой реализуем 3 класса. Первый - отвечает Р·Р° РіСЂРёРґ, выводящий РЅР° правой панели РІСЃРµ товары:

    [ControlAddInExport("Orwell.MoveItemFrom")] 
    public class MoveItemFrom : StringControlAddInBase 
    { 
        private ItemRefr.Item_Service itemList; 
        private ItemRefr.Item[] items;                  
 
        private DataGridView dataGrid; 
        private DataGridViewTextBoxColumn column1; 
        private DataGridViewTextBoxColumn column2;                  
 
        private int rowNo;                  
 
        protected override Control CreateControl() 
        { 
            dataGrid = new DataGridView(); 
            dataGrid.EditMode = DataGridViewEditMode.EditProgrammatically; 
            column1 = new DataGridViewTextBoxColumn(); 
            column2 = new DataGridViewTextBoxColumn(); 
            column1.HeaderText = "No."; 
            column2.HeaderText = "Description"; 
            dataGrid.Columns.AddRange(new DataGridViewColumn[] { column1, column2 });                  
 
            dataGrid.MouseDown += new MouseEventHandler(dataGrid_MouseDown); 
            dataGrid.MouseMove += new MouseEventHandler(dataGrid_MouseMove);                  
 
            rowNo = 0;                  
 
            itemList = new ItemRefr.Item_Service(); 
            itemList.UseDefaultCredentials = true; 
            items = itemList.ReadMultiple(null, null, 0); 
            foreach (ItemRefr.Item item in items) 
            { 
                dataGrid.Rows.Add(); 
                dataGrid.Rows[rowNo].Cells[0].Value = item.No; 
                dataGrid.Rows[rowNo].Cells[1].Value = item.Description; 
                rowNo += 1; 
            }                  
 
            return dataGrid; 
        }                  
 
        void dataGrid_MouseMove(object sender, MouseEventArgs e) 
        { 
            if ((e.Button & MouseButtons.Left) == MouseButtons.Left) 
            { 
                DragDropEffects dropEffect = dataGrid.DoDragDrop(dataGrid.CurrentRow, 
                    DragDropEffects.All | DragDropEffects.Link); 
            } 
        }                  
 
        void dataGrid_MouseDown(object sender, MouseEventArgs e) 
        { 
            if (dataGrid.Rows.Count == 0) 
                return;                  
 
            rowNo = dataGrid.CurrentRow.Index; 
            TheItemToMove.TheItem = (string)dataGrid.Rows[rowNo].Cells[0].Value.ToString(); 
        } 
    }

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

Помимо основных элементов грида, в качестве private членов так же определяем службу, которая опубликована как 30-й Page (карточка товара).

Далее, в методе CreateControl определяем колонки грида и подписываемся на следующие события:

  • нажатие кнопки мышки РЅР° строке РіСЂРёРґР°;
  • перетаскивание строки РіСЂРёРґР°.

Далее, после того, как произошла подписка на указанные события, производим заполнение грида данными о товарах в базе NAV.

В методе dataGrid_MouseDown происходит запоминание выделенного товара и запись номера товара в поле статического класса TheItemToMove (второй класс нашей библиотеки):

public static class TheItemToMove 
    { 
       private static string theItem;               
 
        public static string TheItem 
        { 
            get { return theItem; } 
            set { theItem = value; } 
        } 
    }

Собственно, статический класс РјС‹ используем для того, чтобы третий класс (”РєРѕСЂР·РёРЅР°”) СЃРјРѕРі понять, какой товар необходимо обработать.

Метод dataGrid_MouseMove отвечает Р·Р° создание трейса РІ момент перетаскивания строки товара РѕС‚ грейда Рє полю “РєРѕСЂР·РёРЅР°” Рё Р·Р° саму возможность выделить конкретную строку грейда Рё перетащить ее РІ РєРѕСЂР·РёРЅСѓ.

После определения класса MoveItemFrom, необходимо определить класс MoveItemTo, отвечающий Р·Р° создание Рё резмещение РІ шапке 42-РіРѕ Page (заказ продажи) контрола “РєРѕСЂР·РёРЅР°”:

[ControlAddInExport("Orwell.MoveItemTo")] 
    public class MoveItemTo : StringControlAddInBase 
    { 
        protected override Control CreateControl() 
        { 
            TextBox textBox = new TextBox();           
 
            textBox.AllowDrop = true; 
            textBox.DragOver += new DragEventHandler(textBox_DragOver); 
            textBox.DragDrop += new DragEventHandler(textBox_DragDrop);           
 
            return textBox; 
        }           
 
        void textBox_DragOver(object sender, DragEventArgs e) 
        { 
            if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move) 
            { 
                e.Effect = DragDropEffects.Move; 
            } 
            else 
                e.Effect = DragDropEffects.None; 
        }           
 
        void textBox_DragDrop(object sender, DragEventArgs e) 
        { 
            RaiseControlAddInEvent(1, TheItemToMove.TheItem); 
        } 
    }

Здесь РІСЃРµ также просто…

TextBox подписывается РЅР° событие “поступления” товара (DragOver - вхождение контрола мыши РІ границы текстбокса), СЃ тем, чтобы отобразить РёРєРѕРЅРєСѓ вставки. Рђ далее, после того, как левая РєРЅРѕРїРєР° мыши будет отпущена пользователем, сработает событие DragDrop Рё произойдет вызов триггера OnControlAddIn поля Пейджа, которое связано СЃ данным Add In’РѕРј.

Р’ OnControlAddIn передается значение товара, который был выделен перед тем, как “перетащить” его РІ РєРѕСЂР·РёРЅСѓ. РќСѓ Р° далее РІСЃРµ проще простого: пишем РІ NAV’e небольшую функцию РїРѕ созданию строки заказа продажи. Только предварительно РЅРµ забываем Рѕ РїСЂРёРІСЏР·РєРµ контролов РІ Page СЃ нашими Add Ins:

2.png

Здесь мы опубликовали Add In-ы, прописав название каждого из них. Обратите внимание на одинаковое значение Public Key Token: все дело в том, что библиотека одна и оба класса были определены в ней.

Далее, связываем поле “РєРѕСЂР·РёРЅС‹” РІ шапке заказа продажи СЃ класом-приемником (MoveItemTo):

3.png

Р?, то же самое, РЅРѕ только для правой панели (СЌРєРѕРЅРѕРјСЏ время, СЏВ РІР·СЏР» уже имеющийся FactBox, отображающийся РІ заказе продажи: Page 9087 “Sales Line FactBox”), обозначая “РіСЂРёРґ-источник” товаров:

41.png

Собственно, последний штрих: РІ NAV определим функцию, создающую строки заказа продажи, РІ ответ РЅР° DragDrop-событие, происходящее РІ поле “РєРѕСЂР·РёРЅС‹”:

51.png

В данном примере мы разобрали ситуацию, когда необходимо использование 2 адд инов одновременно. Причем работа одного из них - непосредственно зависит от работы другого. Более того, оба Add Ins реагируют на ряд событий.

Данную разработку можно улучшать, проапгрейдив ее, Рє примеру, РґРѕ WPF приложения СЃ различными “красивостями”: объем заполнения РєРѕСЂР·РёРЅС‹, динамический выбор количества товаров, складов Рё прочее. РќРѕ это уже - дело фантазии. :)

Метки: ,



Оставьте свой отзыв!