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

EaBIM

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
查看: 540|回复: 1
打印 上一主题 下一主题

Parameter of Revit API – 14: Set Parameter Value

[复制链接]

1514

主题

7465

帖子

1万

积分

admin

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

积分
12404

社区QQ达人

跳转到指定楼层
楼主
发表于 2014-1-9 12:25:41 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

Parameter offers a few set methods to assign values to different data types:

Set(ElementId)
Set(Double)
Set(Int32)
Set(String)
Obviously, the first signature is used to assign value for Parameter with ElementId StorageType and the last is for String StorageType. The middle two may confuse people: what will happen if a value of 5 is provided to the Set method of a Double StorageType Parameter and what if a value of 5.0 to of Integer StorageType?

Let’s do a simple test:   
Wall wall = SelectWall(cmdData.Application.ActiveUIDocument.Selection);
List<Parameter> pLst = (from Parameter p in wall.Parameters select p).ToList();
string str = string.Empty;
//Double StorageType
Parameter baseOffsetP = pLst.First(p => p.Definition.Name == "Base Offset");
str += "\nDouble StorageType:\n";
str += string.Format("Before set:{0} \t\tTo:{1} \tRet:{2} \tAfter set:{3}\n", baseOffsetP.AsDouble(), "2*3", baseOffsetP.Set(2*3), baseOffsetP.AsDouble());
str += string.Format("Before set:{0} \t\tTo:{1} \tRet:{2} \tAfter set:{3}\n", baseOffsetP.AsDouble(), "5", baseOffsetP.Set(5), baseOffsetP.AsDouble());
str += string.Format("Before set:{0} \t\tTo:{1} \tRet:{2} \tAfter set:{3}\n", baseOffsetP.AsDouble(), "\"3.3\"", baseOffsetP.Set("3.3"), baseOffsetP.AsDouble());
str += string.Format("Before set:{0} \t\tTo:{1} \tRet:{2} \tAfter set:{3}\n", baseOffsetP.AsDouble(), "3/1.5", baseOffsetP.Set(3/1.5), baseOffsetP.AsDouble());
//Integer StorageType
Parameter strucUsageP = pLst.First(p => p.Definition.Name == "Structural Usage");
str += "\nInteger StorageType:\n";
str += string.Format("Before set:{0} \t\tTo:{1} \tRet:{2} \tAfter set:{3}\n", strucUsageP.AsInteger(), "\"2\"", strucUsageP.Set("2"), strucUsageP.AsInteger());
str += string.Format("Before set:{0} \t\tTo:{1} \tRet:{2} \tAfter set:{3}\n", strucUsageP.AsInteger(), "1.0", strucUsageP.Set(1.0), strucUsageP.AsInteger());
str += string.Format("Before set:{0} \t\tTo:{1} \tRet:{2} \tAfter set:{3}\n", strucUsageP.AsInteger(), "3*2.1", strucUsageP.Set(3*2.1), strucUsageP.AsInteger());
//String StorageType
Parameter markP = pLst.First(p => p.Definition.Name == "Mark");
str += "\nString StorageType:\n";
str += string.Format("Before set:{0} \t\tTo:{1} \tRet:{2} \tAfter set:{3}\n", markP.AsString(), "2", markP.Set(2), markP.AsString());
str += string.Format("Before set:{0} \t\tTo:{1} \tRet:{2} \tAfter set:{3}\n", markP.AsString(), "\"3.1\"", markP.Set("3.1"), markP.AsString());
MessageBox.Show(str, "Parameter Set Signatures and Results");
Some information like the following may be outputted:



The results are not as expected or documented, are they? For a Double StorageType Parameter, its Set method can accept an INTEGER argument! For an Integer StorageType Parameter, its Set method accepts a double value, 1.0!

The trickiest part is the return values in all these cases are all TRUE!
It is good that the Parameter.Set() method offers some flexibility but at the same time it brings confusion. Similar situation is with the SetValueString() method.
The following might not make much sense but they do make things clearer:
SetElementId(ElementId)
SetDouble(Double)
SetInteger(Int32)
SetString(String)
If the flexibility has higher priority, a method like the following is obviously better:

public static void SetParameterValue(Parameter p, object value)
{
    try
    {
        if (value.GetType().Equals(typeof(string)))
        {
            if (p.SetValueString(value as string))
                return;
        }
        switch (p.StorageType)
        {
            case StorageType.None:
                break;
            case StorageType.Double:
                if (value.GetType().Equals(typeof(string)))
                {
                    p.Set(double.Parse(value as string));
                }
                else
                {
                    p.Set(Convert.ToDouble(value));
                }
                break;
            case StorageType.Integer:
                if (value.GetType().Equals(typeof(string)))
                {
                    p.Set(int.Parse(value as string));
                }
                else
                {
                    p.Set(Convert.ToInt32(value));
                }
                break;
            case StorageType.ElementId:
                if (value.GetType().Equals(typeof(ElementId)))
                {
                    p.Set(value as ElementId);
                }
                else if (value.GetType().Equals(typeof(string)))
                {
                    p.Set(new ElementId(int.Parse(value as string)));
                }
                else
                {
                    p.Set(new ElementId(Convert.ToInt32(value)));
                }
                break;
            case StorageType.String:
                p.Set(value.ToString());
                break;
        }
    }
    catch
    {
        throw new Exception("Invalid Value Input!");
    }
}
All possible good values will be accepted and the best intelligence can be achieved. The following code can be used to exercise the help method:

Wall wall = SelectWall(cmdData.Application.ActiveUIDocument.Selection);
List<Parameter> pLst = (from Parameter p in wall.Parameters select p).ToList();
//Double StorageType
Parameter baseOffsetP = pLst.First(p=>p.Definition.Name == "Base Offset");
SetParameterValue(baseOffsetP, "2'3\"");
SetParameterValue(baseOffsetP, "15");
SetParameterValue(baseOffsetP, "14.7");
SetParameterValue(baseOffsetP, 11);
SetParameterValue(baseOffsetP, 7.1);
try
{
    SetParameterValue(baseOffsetP, "abc");
}
catch (Exception e)
{
    MessageBox.Show(e.Message);
}
//Integer StorageType
Parameter strucUsageP = pLst.First(p => p.Definition.Name == "Structural Usage");
SetParameterValue(strucUsageP, "2");
SetParameterValue(strucUsageP, 1.0);
SetParameterValue(strucUsageP, 2L);
SetParameterValue(strucUsageP, 0);
try
{
    SetParameterValue(strucUsageP, wall);
}
catch (Exception e)
{
    MessageBox.Show(e.Message);
}
//String StorageType
Parameter markP = pLst.First(p => p.Definition.Name == "Mark");
SetParameterValue(markP, "Test by Spiderinnet");
SetParameterValue(markP, 123456.789);
SetParameterValue(markP, 2L);
SetParameterValue(markP, wall);
try
{
    SetParameterValue(markP, null);
}
catch (Exception e)
{
    MessageBox.Show(e.Message);
}
If an extension method for the Parameter class seems better, here it is:
#region Namespaces
using System;
using System.Text;
using System.Linq;
using System.Xml;
using System.Reflection;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Forms;
using System.IO;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Events;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using Autodesk.Revit.UI.Events;
using Autodesk.Revit.Collections;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.Utility;
using RvtApplication = Autodesk.Revit.ApplicationServices.Application;
using RvtDocument = Autodesk.Revit.DB.Document;
#endregion
namespace RevitAddinCS
{
    public static class ParameterExtension
    {
        public static void SetValue(this Parameter p, object value)
        {
            try
            {
                if (value.GetType().Equals(typeof(string)))
                {
                    if (p.SetValueString(value as string))
                        return;
                }
                switch (p.StorageType)
                {
                    case StorageType.None:
                        break;
                    case StorageType.Double:
                        if (value.GetType().Equals(typeof(string)))
                        {
                            p.Set(double.Parse(value as string));
                        }
                        else
                        {
                            p.Set(Convert.ToDouble(value));
                        }
                        break;
                    case StorageType.Integer:
                        if (value.GetType().Equals(typeof(string)))
                        {
                            p.Set(int.Parse(value as string));
                        }
                        else
                        {
                            p.Set(Convert.ToInt32(value));
                        }
                        break;
                    case StorageType.ElementId:
                        if (value.GetType().Equals(typeof(ElementId)))
                        {
                            p.Set(value as ElementId);
                        }
                        else if (value.GetType().Equals(typeof(string)))
                        {
                            p.Set(new ElementId(int.Parse(value as string)));
                        }
                        else
                        {
                            p.Set(new ElementId(Convert.ToInt32(value)));
                        }
                        break;
                    case StorageType.String:
                        p.Set(value.ToString());
                        break;
                }
            }
            catch
            {
                throw new Exception("Invalid Value Input!");
            }
        }
    }
}


And the following code can be used to exercise the extension method:
Wall wall1 = SelectWall(cmdData.Application.ActiveUIDocument.Selection);
List<Parameter> pLst1 = (from Parameter p in wall1.Parameters select p).ToList();
//Double StorageType
Parameter baseOffsetP1 = pLst1.First(p => p.Definition.Name == "Base Offset");
baseOffsetP1.SetValue("2'3\"");
baseOffsetP1.SetValue("15");
baseOffsetP1.SetValue("14.7");
baseOffsetP1.SetValue(11);
baseOffsetP1.SetValue(7.1);
try
{
    baseOffsetP1.SetValue("abc");
}
catch (Exception e)
{
    MessageBox.Show(e.Message);
}
//Integer StorageType
Parameter strucUsageP1 = pLst1.First(p => p.Definition.Name == "Structural Usage");
strucUsageP1.SetValue("2");
strucUsageP1.SetValue(1.0);
strucUsageP1.SetValue(2L);
strucUsageP1.SetValue(0);
try
{
    strucUsageP1.SetValue(wall);
}
catch (Exception e)
{
    MessageBox.Show(e.Message);
}
//String StorageType
Parameter markP1 = pLst1.First(p => p.Definition.Name == "Mark");
markP1.SetValue("Test by Spiderinnet");
markP1.SetValue(123456.789);
markP1.SetValue(2L);
markP1.SetValue(wall);
try
{
    markP1.SetValue(null);
}
catch (Exception e)
{
    MessageBox.Show(e.Message);
}
Parameter Writer of RevitAddinWizardwill provide the intelligence in no time.

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

28

主题

924

帖子

2115

积分

BIM经理

Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6Rank: 6

积分
2115
2F
发表于 2014-2-20 15:00:25 | 只看该作者
顶...... 楼下跟上.....
*滑块验证:
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-16 13:47

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

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