Skip to content

数据管理

TIP

本部分依赖数据模块,即需要安装AnyCAD.Platform.NET模块。

数据管理模块提供基于文档的数据管理方式,支持文件的读写、对象增删改查、事务机制(Undo/Redo)等功能。

虽然基于基础模块也能开发应用,但对于比较复杂的应用,比如需要文件保存/事务回退等功能,基于数据管理模块提供的基础能力,可以大大提升应用的开发效率。

1. 核心概念

应用 Application

全局唯一

用来管理多文档、多视图。可以用来获取全局对象,如当前活动的视图、文档等。

文档 Document

即对象的容器。

只有在Document中的对象才能够被序列化、支持事务处理。

csharp
// 获取当前活动的文档
var doc = Application.Instance().GetActiveDocument();

基本对象 Element

图元或对象的基类,可以是实体构件,也可以是材质、分组等虚拟对象。

保存在文档里的对象均为Element。每个Element对象都会分配全局唯一的Id。通过Id可以从文档中查找对象。

从Element的API文档中的类图可以看到,从Element继承了若干的子类,以满足不同的应用需求。

视图 DbViewBase

我们对文档多个维度查看,每个维度称之为视图。

AnyCAD支持多视图。创建文档的时候,默认创建三维视图。在单视图应用可以忽略视图的存在。

事务 UndoTransaction

即Undo/Redo功能

对Document、Element的增删改均需要使用事务对象来管理。其一般的范式为:

csharp

var undo = new UndoTransaction(doc);
undo.Start("Modify"); // 自己定义本次事务的内容
{
    // 这里对文档、图元操作处理
}
undo.Commit(); //提交事务

2. 增删改查

与数据库一样,AnyCAD支持对文档内的对象记录的增删改查。

以创建几何实体图元 ShapeElement 为例, 实现对象增删改查。

TIP

ShapeElement用来保存几何对象,对于大多数用户创建的几何实体保存在此对象即可。

增加和修改

csharp
// 创建文档
var doc = Application.Instance().CreateDocument("我的文档");

// 显示文档
Application.Instance().ShowDocument(doc);

ObjectId shapeId;
// 添加对象
var undo = new UndoTransaction(doc);
undo.Start("Add"); // 自己定义本次事务的内容
{
    // ShapeElement
    var se = ShapeElement.Create(doc);
    // 创建几何对象  
    var shape = ShapeBuilder.MakeBox(....);
    se.SetShape(se);

    shapeId = se.GetId();
}
undo.Commit(); //提交事务

删除

通过对象ID从文档中删除对象。

csharp
// 删除对象
var undo = new UndoTransaction(doc);
undo.Start("Remove"); // 自己定义本次事务的内容
{
    doc.RemoveElement(shapeId);
}
undo.Commit(); //提交事务

查找

  • 根据ID查找对象
csharp
 var se = ShapeElement.Cast(doc.FindElement(shapeId));
  • 遍历文档

使用ElementIterator遍历文档全部的对象:

csharp
for(var itr = ElementIterator.Create(doc); itr.More(); itr.Next())
{
    var e = itr.Current();
    //...
}
  • 遍历某类对象

遍历ShapeElement类型的对象

csharp
var itr = ElementIterator.Create(doc, ShapeElement.GetStaticClassId());
for(; itr.More(); itr.Next())
{
    var e = ShapeElement.Cast(itr.Current());
    if(e == null)
        continue;
    //...
}

3. 文档监听

使用DocumentListener继承的子类可以监听文档变化状态,以便及时更新界面状态。

把对象注册到事件管理器DocumentEvent

  • 定义监听器
csharp

class MyDocumentListener : DocumentListener
{
    public MyDocumentListener()
    {
        SetName("HelloWorld");
    }

    public override	AfterDocumentChanged (Document doc, DocumentEventArgs args)
    {
        // 根据args状态判断是否需要更新界面,比如构件目录树
    }

    public override	OnSelectionChanged(Document doc, ObjectId viewId)
    {
        // 选择集发生变化,用来更新构件树上选择状态、属性表上的属性等
    }    
}
  • 注册监听器
csharp

//一般声明为成员变量
MyDocumentListener _DocListener = new MyDocumentListener();

DocumentEvent.Instance().AddListener(_DocListener);

// ...
  • 移除监听器
csharp
// 必要的地方移除
DocumentEvent.Instance().RemoveListener (_DocListener);

4. 对象显示

基于数据模块,开发者不需要直接操作显示场景,对Element的增删改会自动更新于文档绑定的视图。

5. 对象选择

使用Document对象的Select选择对象,使用GetSelection方法获取选中对象ID集合。

  • 视图选择

用户点击视图选择对象会自动更新Document的选择集

  • 手动选择

如通过选择目录树的一项选择

csharp
ObjectIdList ids = new ObjectIdList();
ids.Add(id);
doc.Select(ids);
// 视图里对应的对象会高亮显示。
// 会自动触发SelectionChanged消息,通过DocumentListener可获取到。
  • 选择集查询
csharp

var ids = doc.GetSelection();
foreach(var id in ids)
{
    //...
}

6. 文档存储

DocumentIO提供Save/Load方法可以保存和加载文档。

  • 保存
csharp
DocumentIO.Save(doc, "d:/ssss.acad");
  • 读取
csharp
var doc = DocumentIO.Load("d:/ssss.acad");
if(doc != null)
{
    //显示文档
    Application.Instance().ShowDocument(doc);
}

7. 小结

使用数据管理模块,需要按照数据模块管理的规则使用,尤其注意事务机制的使用方法。通过DocumentListener可以实现界面与视图之间的解耦,在需要获取文档变化、选择状态的地方均可以注册相应的DocumentListener来对文档监听。

为方便数据模块的在WPF中的使用,可以结合AnyCAD.AppFramework.NET MVVM框架,可大大简化代码量。请参考示例程序源码 anycad.rapid.cax


上海图无形科技有限公司旗下产品
Copyright © 2013-2024 AnyCAD