Инструменты пользователя

Инструменты сайта


developers:tutorial:createmodel

Различия

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

Ссылка на это сравнение

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
developers:tutorial:createmodel [2019/02/16 20:25]
vasya
developers:tutorial:createmodel [2022/03/15 19:14] (текущий)
proxor
Строка 13: Строка 13:
  
 Для подключения собственной модели к комплексу,​ необходимо выполнить следующие действия:​ Для подключения собственной модели к комплексу,​ необходимо выполнить следующие действия:​
 +  * Создать класс модели,​ реализующий интерфейс [[developers:​references:​topomatic.foundationclasses.istatecontroller|IStateController]],​ это необходимо для того чтобы была возможность определять состояние модели и была ли она изменена.
   * Создать класс редактора модели,​ наследник от [[developers:​references:​topomatic.applicationplatform.core.modeleditor|ModelEditor]],​ предназначенный для реализации загрузки,​ сохранения и открытия модели   * Создать класс редактора модели,​ наследник от [[developers:​references:​topomatic.applicationplatform.core.modeleditor|ModelEditor]],​ предназначенный для реализации загрузки,​ сохранения и открытия модели
   * Написать метод, который возвращает экземпляр наследника от [[developers:​references:​topomatic.applicationplatform.core.modeleditor|ModelEditor]] и декорировать его атрибутом "​cmd"​   * Написать метод, который возвращает экземпляр наследника от [[developers:​references:​topomatic.applicationplatform.core.modeleditor|ModelEditor]] и декорировать его атрибутом "​cmd"​
Строка 18: Строка 19:
   * В файле *.plugin в секции [[developers:​references:​core.plugin:​cores|cores]] описать вид модели в структуре проекта,​ а в секции [[developers:​references:​core.plugin:​coreitems|coreitems]] включить модель в состав стандартного проекта. ​   * В файле *.plugin в секции [[developers:​references:​core.plugin:​cores|cores]] описать вид модели в структуре проекта,​ а в секции [[developers:​references:​core.plugin:​coreitems|coreitems]] включить модель в состав стандартного проекта. ​
  
 +<​note>​
 +Большая часть методов интерфейса [[developers:​references:​topomatic.foundationclasses.istatecontroller|IStateController]] реализована в классе [[developers:​references:​topomatic.foundationclasses.statecontrollerobject|StateControllerObject]].
 +Редактор модели на видовом экране окна план и других системных окон нужно наследовать от [[developers:​references:​topomatic.applicationplatform.core.planmodeleditor|PlanModelEditor]].
 +Редактор модели в отдельном окне нужно наследовать от [[developers:​references:​topomatic.applicationplatform.core.documentmodeleditor|DocumentModelEditor]]
 +</​note>​
  
 Для реализации сохранения и загрузки в программном комплексе [[http://​www.topomatic.ru|Топоматик Робур]] используется сборка [[developers:​references:​topomatic.stg|Topomatic.Stg.dll]]. За сохранение отвечает интерфейс [[developers:​references:​topomatic.stg.istgserializable|IStgSerializable]],​ который состоит из двух методов - [[developers:​references:​topomatic.stg.istgserializable.loadfromstg_topomatic.stg.stgnode|LoadFromStg]] для загрузки ​ Для реализации сохранения и загрузки в программном комплексе [[http://​www.topomatic.ru|Топоматик Робур]] используется сборка [[developers:​references:​topomatic.stg|Topomatic.Stg.dll]]. За сохранение отвечает интерфейс [[developers:​references:​topomatic.stg.istgserializable|IStgSerializable]],​ который состоит из двух методов - [[developers:​references:​topomatic.stg.istgserializable.loadfromstg_topomatic.stg.stgnode|LoadFromStg]] для загрузки ​
Строка 52: Строка 58:
 С помощью диалогового окна Менеджер ссылок добавьте ссылки на следующие библиотеки:​ С помощью диалогового окна Менеджер ссылок добавьте ссылки на следующие библиотеки:​
  
 +  * [[developers:​references:​topomatic.cad.foundation|Topomatic.Cad.Foundation.dll]] - базовые математические типы и операции
   * [[developers:​references:​topomatic.controls|Topomatic.Controls.dll]] - базовые диалоги и таблицы   * [[developers:​references:​topomatic.controls|Topomatic.Controls.dll]] - базовые диалоги и таблицы
  
 +Создайте новый класс Model.cs для реализации нашей модели.
 +<code csharp>
 +{
 +    //​Класс реализующий структуру данных нашей модели
 +    //для поддержки интерфейса IStateController наследуем от StateControllerObject
 +    class Model : StateControllerObject,​ IStgSerializable
 +    {
 +        private bool m_ReadOnly = false;
 +
 +        //​Строковое значение
 +        public string StringValue = "​Строка";​
 +
 +        //​Булево значение
 +        public bool BooleanValue = false;
 +
 +        //​Значение с плавающей точкой
 +        public double DoubleValue = 10.5;
 +
 +        //​Целое значение
 +        public int IntValue = 10;
 +
 +        //​Список строковых значений
 +        public List<​string>​ ArrayValues = new List<​string>​();​
 +
 +        //флаг только для чтения
 +        public override bool ReadOnly
 +        {
 +            get
 +            {
 +                return m_ReadOnly;
 +            }
 +
 +            set
 +            {
 +                m_ReadOnly = value;
 +            }
 +        }
 +
 +        //​Загрузка из узла
 +        public void LoadFromStg(StgNode node)
 +        {
 +            //Все значения загружаем с указанием значения по умолчанию
 +            BooleanValue = node.GetBoolean("​BooleanValue",​ false);
 +            StringValue = node.GetString("​StringValue",​ "​Строка"​);​
 +            DoubleValue = node.GetDouble("​DoubleValue",​ 10.5);
 +            IntValue = node.GetInt32("​IntValue",​ 10);
 +            ArrayValues.Clear();​
 +            //При загрузке массива указывается тип составляющих массив значений
 +            var array = node.GetArray("​ArrayValues",​ StgType.String);​
 +            for (int i = 0; i < array.Count;​ i++)
 +            {
 +                ArrayValues.Add(array.GetString(i));​
 +            }
 +        }
 +
 +        //​Сохранение в узел
 +        public void SaveToStg(StgNode node)
 +        {
 +            //​Сохраняем значения в узел
 +            node.AddBoolean("​BooleanValue",​ BooleanValue);​
 +            node.AddString("​StringValue",​ StringValue);​
 +            node.AddDouble("​DoubleValue",​ DoubleValue);​
 +            node.AddInt32("​IntValue",​ IntValue);
 +            //​Сохраняем массив с указанием типа значений
 +            var array = node.AddArray("​ArrayValues",​ StgType.String);​
 +            for (int i = 0; i < ArrayValues.Count;​ i++)
 +            {
 +                array.AddString(ArrayValues[i]);​
 +            }
 +        }
 +    }
 +}
 +</​code>​
 +
 +И класс Editor.cs реализующий редактор модели
 +
 +<code csharp>
 +{
 +    //​Класс реализующий редактор нашей модели
 +    class Editor : ModelEditor
 +    {
 +        //​Реализация загрузки модели по указанному пути, должна вернуть реализацию класса нашей модели
 +        public override object LoadFromFile(string fullpath)
 +        {
 +            //​создаем экземпляр класса модели
 +            var model = new Model();
 +            //если fullpath null - то необходимо просто вернуть экземпляр класса модели,​ без загрузки данных
 +            if (fullpath != null)
 +            {
 +                //​создаем файловый поток
 +                using (var stream = new FileStream(fullpath,​ FileMode.Open,​ FileAccess.Read,​ FileShare.Read))
 +                {
 +                    //​создаем документ для работы с Topomatic.Stg
 +                    var document = new StgDocument();​
 +                    //​загружаем документ из потока в бинарном виде
 +                    document.LoadFromStreamAsBinary(stream);​
 +                    //​загружаем данные нашей модели из документа
 +                    model.LoadFromStg(document.Body);​
 +                }
 +            }
 +            //​всегда возвращаем экземпляр модели
 +            return model;
 +        }
 +
 +        //​Реализация сохранения модели по указанному пути
 +        public override void SaveToFile(object model, string fullpath)
 +        {
 +            //в качестве параметра model приходит наша модель данных
 +            var m = model as Model;
 +            if (m != null)
 +            {
 +                //​создаем файловый поток
 +                using (var stream = new FileStream(fullpath,​ FileMode.Create,​ FileAccess.Write,​ FileShare.None))
 +                {
 +                    //​создаем документ для работы с Topomatic.Stg
 +                    var document = new StgDocument();​
 +                    //​сохраняем данные нашей модели в документ
 +                    m.SaveToStg(document.Body);​
 +                    //​сохраняем документ в потока в бинарном виде
 +                    document.SaveToStreamAsBinary(stream);​
 +                }
 +            }
 +        }
 +
 +        //​Реализация открытия модели по команде "​open"​
 +        public override IEditorResult Open(IProjectModel model)
 +        {
 +            var cursor = Cursor.Current;​
 +            Cursor.Current = Cursors.WaitCursor;​
 +            try
 +            {
 +                //В нашем поросто возвращаем реализацию интерфеса IEditorResult
 +                return new EditorResult();​
 +            }
 +            finally
 +            {
 +                Cursor.Current = cursor;
 +            }
 +        }
 +
 +        //​Реализация интерфейса IEditorResult
 +        private class EditorResult : IEditorResult
 +        {
 +            private bool m_Opened;
 +
 +            public EditorResult()
 +            {
 +                m_Opened = true;
 +            }
 +
 +            //​Необходимо реализовать флаг, показывающий открыта модель или нет
 +            public bool Opened
 +            {
 +                get
 +                {
 +                    return m_Opened;
 +                }
 +            }
 +
 +            //​Необходимо реализовать метод закрытия модели
 +            public void Close()
 +            {
 +                //В нашем случае мы просто управляем флагом и все
 +                m_Opened = false;
 +            }
 +
 +            //И метод перезагрузки модели
 +            public void Reload()
 +            {
 +                //​Здесь нам ничего не нужно делать
 +            }
 +        }
 +    }
 +}
 +</​code>​
 +
 +В нашем случае редактор модели получился достаточно простым,​ поскольку наша модель не реагирует на команду открыть и фактически вся работа с ней будет происходить в отдельной команде для редактирования модели.
 +Дополнительно необходимо реализовать [[developers:​tutorial:​dlgandpropertygrid|диалог]] для редактирования данных модели. Его реализацию можно увидеть в исходных кодах примера.
 +
 +В теле программного модуля необходимо объявить функции для создания и редактирования модели,​ функцию для создания редактора и регистрации модели.
 +<code csharp>
 +    partial class Module : Topomatic.ApplicationPlatform.Plugins.PluginInitializator
 +    {
 +        //​функция создает экземпляр редактора модели и возвращает его
 +        [cmd("​create_testmodel_editor"​)]
 +        public Editor CreateEditor()
 +        {
 +            return new Editor();
 +        }
 +
 +        //​функция создает новую модель и возвращает её
 +        [cmd("​create_testmodel"​)]
 +        private object CreateModel(object[] args)
 +        {
 +            //​получаем текущий активный проект
 +            var project = ApplicationHost.Current.ActiveProject as ModelProject;​
 +            Debug.Assert(project != null);
 +            if (project != null)
 +            {
 +                //​запускаем групповое изменение свойств
 +                project.TransactionManager.BeginUpdate();​
 +                try
 +                {
 +                    string folder;
 +                    if ((args != null) && (args.Length > 0) && (args[0] != null))
 +                    {
 +                        //В качестве аргумента приходит либо идентификатор каталога внутри проекта
 +                        folder = args[0].ToString();​
 +                    }
 +                    else
 +                    {
 +                        //либо мы создаем ​ этот идентификатор самостоятельно
 +                        folder = PluginCoreOps.FindModelPathId(PluginCoreOps.CreateFolder(new string[] { "​Модели",​ "​Тестовые модели"​ }));
 +                    }
 +                    //​создаем модель с помощью команды "​mkitem"​
 +                    //в неё мы передаем идентификатор каталога и тип нашей модели
 +                    return ApplicationHost.Current.Plugins.Execute("​mkitem",​ new object[] { folder, "​testmodel"​ });
 +                }
 +                finally
 +                {
 +                    project.TransactionManager.EndUpdate();​
 +                }
 +            }
 +            else
 +            {
 +                throw new OperationCanceledException();​
 +            }
 +        }
 +
 +        //​функция позволяет редактировать содержимое нашей модели
 +        [cmd("​edit_testmodel"​)]
 +        private void OpenModel(string pathid)
 +        {
 +            //​получаем IProjectModel используя идентификатор модели
 +            var project_model = PluginCoreOps.FindModel(pathid);​
 +            if (project_model != null)
 +            {
 +                //​вызываем блокировку модели на редактирование
 +                project_model.LockWrite();​
 +                try
 +                {
 +                    //​получаем класс нашей модели
 +                    var model = project_model.LockRead() as Model;
 +                    if (model != null)
 +                    {
 +                        //​вызываем диалог редактирования нашей модели
 +                        if (EditModelDlg.Execute(model))
 +                            project_model.Modified = true;
 +                    }
 +                }
 +                finally
 +                {
 +                    //​снимаем блокировку модели на редактирование
 +                    project_model.UnlockWrite();​
 +                }
 +            }
 +        }
 +
 +        public override void Initialize(PluginFactory factory)
 +        {
 +            base.Initialize(factory);​
 +            //​Регестрируем нашу модель в проекте
 +            factory.RegisterModelEditor("​testmodel", ​
 +                new ModelEditorInfo("​Тестовая модель|*.testmodelx", ​
 +                "​.testmodelx", ​
 +                "​testmodel", ​
 +                "​Тестовая модель", ​
 +                "​create_testmodel_editor"​));​
 +        }
 +    }
 +</​code>​
 +
 +В файле .plugin нужно разместить нашу модель в секции [[developers:​references:​core.plugin:​cores|cores]] и добавить [[developers:​tutorial:​cmdattribute|команды]] для её редактирования и создания.
 +<code javascript>​
 +{
 +  "​assemblies":​ {
 +    "​tutorial6":​ {
 +      "​assembly":​ "​tutorial6.dll,​ tutorial6.ModulePluginHost"​
 +    }
 +  },
 +  "​actions":​ {
 +    "​id_create_testmodel":​ {
 +      "​cmd":​ "​create_testmodel \"​%0\"",​
 +      "​title":​ "​Тестовая модель"​
 +    },
 +    "​id_edit_testmodel":​ {
 +      "​cmd":​ "​edit_testmodel \"​%0\"",​
 +      "​title":​ "​Редактировать..."​
 +    }
 +  },
 +  "​contexts":​ {
 +    "​ctx_mkitem":​ {
 +      "​items":​ [
 +        "​id_create_testmodel \"​%0\""​
 +      ]
 +    },
 +    "​testmodel.context":​ {
 +      "​priority":​ 1001,
 +      "​items":​ [
 +        { "​default":​ "​$(if,​$(opened,​%0),​core.id_close \"​%0\"​ \"​Скрыть модель\",​core.id_open \"​%0\"​ \"​Показать модель\"​)"​ },
 +        "​id_edit_testmodel \"​%0\"",​
 +        "​-",​
 +        "​core.id_rmitem \"​%0\""​
 +      ]
 +    }
 +  },
 +  "​cores":​ {
 +    "​testmodel":​ {
 +      "​title":​ "​$(referencename,​%0)",​
 +      "​description":​ "​Тестовая модель %0",
 +      "​icon":​ "​ic_file",​
 +      "​statusicon":​ "",​
 +      "​flags":​ "​$(modelflags,​%0)",​
 +      "​menu":​ "​testmodel.context \"​%0\""​
 +    }
 +  }
 +}
 +</​code>​
 +Обратите внимание на секцию [[developers:​references:​core.plugin:​contexts|contexts]]. Для добавления возможности создать нашу тестовую модель из контекстного меню каталога проекта,​ мы добавляем функцию создания нашей модели в системное меню "​ctx_mkitem"​.
 +
 +В результате мы получим возможность добавлять в проект наши тестовые модели и редактировать их содержимое по команде "​Редактировать"​ в контекстном меню модели.
 +{{ :​developers:​tutorial:​createmodel:​contexmenu.png?​direct&​600 |}}
 +
 +<​note>​[[developers:​tutorial:​tutorialcode|Исходный код]] примера расположен в проекте **"​tutorial6"​**.</​note>​
developers/tutorial/createmodel.1550348759.txt.gz · Последние изменения: 2021/07/22 14:28 (внешнее изменение)