EaBIM一直以来积极响应国家“十二五”推进建筑业信息化的号召,对建筑领域的信息技术开展深入技术交流和探讨!致力于打造“BIM-建筑师-生态技术”三位一体综合资源交流共享平台,希望为BIM与可持续设计理念及技术的普及做出微小的贡献!!!

EaBIM

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
查看: 665|回复: 2
打印 上一主题 下一主题

Parameter of Revit API – 27: Erase Shared Parameter

[复制链接]

1514

主题

7465

帖子

1万

积分

admin

Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10Rank: 10

积分
12404

社区QQ达人

跳转到指定楼层
楼主
发表于 2014-1-9 12:19:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
We have talked about getting information of shared parameters, attaching a shared parameter to some category instances, and creating new shared parameters. In this article, let’s see how to erase shared parameters or whether it is possible to achieve the goal programmatically with some straightforward APIs.

From checking on some relevant API classes and methods, it seems this is very achievable and in many ways. Firstly, the Definitions class or its parent DefinitionsBase has an Erase(Definition item) method which seems to do the right job; the Document.ParameterBindings property (actually the BindingMap class) has an Erase(Definition item) method too; and better it has another very similar method, Remove(Definition item), which seems to do the same job.
Let’s look at them one by one. The DefinitionsBase.Erase(Definition item) goes the first:
public static List<T> RawConvertSetToList<T>(IEnumerable set)
{
    List<T> list = (from T p in set select p).ToList<T>();
    return list;
}
public static bool RawEraseSharedParameterDefinition(RvtApplication app, string name, string group, ParameterType type)
{
    DefinitionFile defFile = app.OpenSharedParameterFile();
    if (defFile != null)
    {
        DefinitionGroup dg = RawConvertSetToList<DefinitionGroup>(defFile.Groups).FirstOrDefault(g => g.Name == group);
        if (dg != null)
        {
            Definition def = RawConvertSetToList<Definition>(dg.Definitions).FirstOrDefault(d => d.Name == name);
            if (def != null && def.ParameterType == type)
            {
                dg.Definitions.Erase(def);
                return true;
            }
        }
    }  
    return false;
}
Use the following test code to exercise it:
RawEraseSharedParameterDefinition(CachedApp, "Volume41", "Group4", ParameterType.Volume);
However, out of most people’s expections, I believe, the following exception occurs:
Autodesk.Revit.Exceptions.InvalidOperationException: Collection is read-only
   at Autodesk.Revit.DB.DefinitionsBase.Erase(Definition item)
Q: How come?
A: No idea!

So the first most natural way does not work at all!
Let’s try the second approach:
public static bool RawEraseSharedParameterBinding1(RvtApplication app, string name, ParameterType type)
{
    BindingMap map = (new UIApplication(app)).ActiveUIDocument.Document.ParameterBindings;
    DefinitionBindingMapIterator it = map.ForwardIterator();
    it.Reset();
    Definition def = null;
    while (it.MoveNext())
    {
        if (it.Key != null && it.Key.Name == name && type == it.Key.ParameterType)
        {
            def = it.Key;
            break;
        }
    }
    if (def != null)
    {
        map.Erase(def);
    }
    return false;
}
Use the following test code to exercise it:
RawEraseSharedParameterBinding1(CachedApp, "Volume41",ParameterType.Volume);
However another exception occurs:
Autodesk.Revit.Exceptions.InvalidOperationException at Autodesk.Revit.DB.BindingMap.Erase(Definition key)


Explanation: “The method Erase inherited from base class is not permitted for this class.”
Ok, now we have the last candidate left, the BindingMap.Remove(Definition key).
public static bool RawEraseSharedParameterBinding2(RvtApplication app, string name, ParameterType type)
{
    BindingMap map = (new UIApplication(app)).ActiveUIDocument.Document.ParameterBindings;
    DefinitionBindingMapIterator it = map.ForwardIterator();
    it.Reset();
    Definition def = null;
    while (it.MoveNext())
    {
        if (it.Key != null && it.Key.Name == name && type == it.Key.ParameterType)
        {
            def = it.Key;
            break;
        }
    }
    if (def != null)
    {
        map.Remove(def);
    }
    return false;
}

RawEraseSharedParameterBinding2(CachedApp, "Volume41",ParameterType.Volume);
No exception occurs this time, but readers may come up with some questions:
1. What does the method really do for us?
2. Why is the Definition from the DefinitionBinding always InternalDefiniton?
3. Will it also delete the shared parameter definition entry in the external DefinitionFile?
4. If the answer to the above is NO, how to do so programmatically?
A1:
The method removes the parameter binding actually just as its name suggests. Or speak it another way, the purpose of the method is to remove a project parameter instead of a shared parameter. And it is model specific rather than application specific which can be seen from the place they come from. The ParameterBindings comes from a Revit Document but the DefinitionFile is associated with the Revit Application through its SharedParametersFilename property and can be retrieved directly through the OpenSharedParameterFile() method call.
Still confused? Don’t worry. We will get it finally.
Let’s try to explain a bit more and demonstrate with some concrete examples. If the shared parameter ‘Volume41’ is defined but not bound at all to any categories or not linked/converted to a project parameter, the above approach does nothing at all. If a non-shared and bound parameter (or call it ‘naked project parameter’ if we like) has the same name as the shared parameter of our real concern, the non-shared parameter will be mistakenly removed from the current model and from all related elements/categories, all existing data will be lost, and all affected schedules and tags will look different! That could be a disaster in the real design world. It also violates the safety rules that Revit tries to build up for us, removing shared parameters will not affect any existing data, elements, and models. If we delete shared parameters programmatically this way, it goes exactly onto the opposite way.
To make it clearer, here is a screenshot which shows some project parameters (or call them bound parameters if we like):

  
The first and the last ones are defined from shared parameters in the same sample ExternalFile that we addressed before. The middle three are real (or naked) project parameters. If you’d like to play around these a bit further, please rename any of the middle three as ‘Volume41’ with or without removing the last one, give the code one more try, and see what will be going on.
So the third approach is really to delete a Project Parameter or parameter DefinitionBinding rather than a shared parameter. Totally different things!
The first approach is the right one but it does not work!
A2: Not so sure. Maybe to tell us that bound shared parameters are the same as other project parameters now and do not behave as ‘shared parameters’ anymore.
A3: No, not at all.
A4:  We will address it in another future post.
Revit Addin Coder of RevitAddinWizardcan help address and clarify various parameter matters including built-in parameter, family parameter, shared parameter, project parameter and more.


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 转播转播 分享分享 分享淘帖 支持支持 反对反对
工作时间:工作日的9:00-12:00/13:30-18:00,节假日不在线,请勿留言

0

主题

3

帖子

27

积分

BIM书童

Rank: 1

积分
27
3F
发表于 2015-8-30 16:40:49 | 只看该作者
创建完这些参数后,我把参数文件的路径都删了,不过程序并没有出错,而且有时候会重复添加共享参数,是为什么?可以指教下吗
*滑块验证:
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|EaBIM网 ( 苏ICP备2020058923号-1  苏公网安备32011502011255号

GMT+8, 2024-11-16 12:46

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表