Это старая версия документа.
Каждая модель данных в комплексе Топоматик Робур располагается в рамках отдельного файла, включенного в состав проекта. С программной точки зрения модель представляет собой экземпляр класса, реализующий интерфейс IProjectModel. Основные методы этого интерфейса это:
Для чтения данных из модели используется метод LockRead(). Если данные модели необходимо изменить, то перед вызовом LockRead() необходимо вызвать LockWrite(), а после UnockWrite().
Для подключения собственной модели к комплексу, необходимо выполнить следующие действия:
Для реализации сохранения и загрузки в программном комплексе Топоматик Робур используется сборка Topomatic.Stg.dll. За сохранение отвечает интерфейс IStgSerializable, который состоит из двух методов - LoadFromStg для загрузки и SaveToStg для сохранения. Оба метода в качестве параметра принимают экземпляр класса StgNode. Методы этого класса позволяют сохранить в узел и загрузить из узла все базовые типы данных, а также дополнительные узлы StgNode и массивы элементов, используя именованные элементы. Кроме того у каждого метода есть перекрытое значение, со значением по умолчанию. Значение по умолчанию будет использовано в том случае, если в загружаемом файле нет такого именованного элемента. Например:
{ .... private double m_Value1 = 0.0; private string m_Value2 = 0.0; void LoadFromStg(StgNode node) { //Если в сохраненном файле нет значения с ключом Value1 будет брошено исключение m_Value1 = node.GetDouble("Value1"); //Если в сохраненном файле нет значения с ключом Value2, //то переменной m_Value2 будет присвоено значение "defaultValue" m_Value2 = node.GetString("Value2", "defaultValue"); } ... }
Использование именованных элементов позволяет легко расширять и дополнять функции загрузки и сохранения по мере расширения модели данных.
Создайте и настройте новый модуль для подключения к программному комплексу Топоматик Робур.
С помощью диалогового окна Менеджер ссылок добавьте ссылки на следующие библиотеки:
Создайте новый класс Model.cs для реализации нашей модели.
{ //Класс реализующий структуру данных нашей модели //для поддержки интерфейса 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]); } } } }
И класс Editor.cs реализующий редактор модели
{ //Класс реализующий редактор нашей модели class Editor : ModelEditor { //Ссылки на другие модели в структуре public override ModelReference[] GetReferences(object model) { //В нашем случае никаких ссылок нет return null; } //Реализация загрузки модели по указанному пути, должна вернуть реализацию класса нашей модели 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() { //Здесь нам ничего не нужно делать } } } }