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

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


developers:tutorial:createmodel

Различия

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

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

Предыдущая версия справа и слева Предыдущая версия
Следующая версия
Предыдущая версия
developers:tutorial:createmodel [2019/02/16 23:39]
vasya
developers:tutorial:createmodel [2022/03/15 19:14] (текущий)
proxor
Строка 21: Строка 21:
 <​note>​ <​note>​
 Большая часть методов интерфейса [[developers:​references:​topomatic.foundationclasses.istatecontroller|IStateController]] реализована в классе [[developers:​references:​topomatic.foundationclasses.statecontrollerobject|StateControllerObject]]. Большая часть методов интерфейса [[developers:​references:​topomatic.foundationclasses.istatecontroller|IStateController]] реализована в классе [[developers:​references:​topomatic.foundationclasses.statecontrollerobject|StateControllerObject]].
-Редактор модели на видовом экране окна план и других системных окон нужно наследовать от [[developers:​references:​topomatic.applicationplatform.core.documentmodeleditor|PlanModelEditor]].+Редактор модели на видовом экране окна план и других системных окон нужно наследовать от [[developers:​references:​topomatic.applicationplatform.core.planmodeleditor|PlanModelEditor]].
 Редактор модели в отдельном окне нужно наследовать от [[developers:​references:​topomatic.applicationplatform.core.documentmodeleditor|DocumentModelEditor]] Редактор модели в отдельном окне нужно наследовать от [[developers:​references:​topomatic.applicationplatform.core.documentmodeleditor|DocumentModelEditor]]
 </​note>​ </​note>​
Строка 135: Строка 135:
 </​code>​ </​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.1550360396.txt.gz · Последние изменения: 2021/07/22 14:28 (внешнее изменение)