搜索
查看
编辑修改
首页
UNITY
NODEJS
PYTHON
AI
GIT
PHP
GO
CEF3
JAVA
HTML
CSS
搜索
笔触狂放9
这个屌丝很懒,什么也没留下!
关注作者
热门标签
jquery
HTML
CSS
PHP
ASP
PYTHON
GO
AI
C
C++
C#
PHOTOSHOP
UNITY
iOS
android
vue
xml
爬虫
SEO
LINUX
WINDOWS
JAVA
MFC
CEF3
CAD
NODEJS
GIT
Pyppeteer
article
热门文章
1
c# 在mono上的移植 系列之一 邮件发送不工作了
2
Node.js+vue+mysql高校人事管理系统7sgv0
3
《区块链公链数据分析简易速速上手小册》第10章:未来趋势和挑战(2024 最新版)
4
TensorFlow tf.data 导入数据(tf.data官方教程) * * * * *_tf dataload
5
基于无监督学习的图像分类:从图像中提取特征_图像分类前的特征提取
6
提高开发效率的必备!超实用的VSCode插件推荐_vscode显示插件大小的插件
7
se(3)-TrackNet: 数据驱动的动态6D物体姿态跟踪, 基于合成域的图片残差校准
8
安装opencv3编译cmake错误:Configuring incomplete, errors occurred_/home/pi/opencv-3.4.1/build/cmakefiles/cmakeoutput
9
鸿蒙HarmonyOS实战-ArkTS语言(渲染控制)_unction return type inference is limited (arkts-no
10
PyCharm社区版安装教程
当前位置:
article
> 正文
Autodesk官方最新的.NET教程(五)(C#版) _c# autocad allowsubselections 什么意思
作者:笔触狂放9 | 2024-02-19 01:20:02
赞
踩
c# autocad allowsubselections 什么意思
第
5
章
用户互操作:提示和选择
背景
提示通常包含一个描述性信息,伴随一个停止以让用户理解所给的信息并输入数据。数据可以通过多种方式被输入,如通过命令行、对话框或AutoCAD编辑窗口。给出的提示要遵循一定的格式,格式要与一般的AutoCAD提示相一致,这一点是非常重要的。例如,关键字要用“/”号分隔并放在方括号“[]”中,缺省值要放在“<>”内。对于一个AutoCAD用户来说,坚持统一的格式将会减少信息理解错误的产生。
当用户在AutoCAD命令行中选择一个实体时,实体是使用选择机制被选择的。这种机制包括一个提示,用来让用户知道选择什么并怎样选择(如,窗口或单一实体),然后是一个停顿。
试一下诸如PINE这种命令来看一下提示的显示,PEDIT来看一下使用单一实体或多线来进行选择。
练习
Prompts
:
提示:
在本章中,我们将提示输入雇员名字、职位、薪水和部门来创建一个雇员块索引对象。如果输入的部门不存在,我们将提示输入部门经理的名字来创建一个新的部门。在我们继续之前,让我们试着重用以前的代码。
为了进行选择,我们将提示用户在一个窗口中进行选择或选择一个实体,而我们只显示选择集中的雇员对象。
在前面的章节中,我们创建了一个名叫“Earnest Shackleton”的雇员,名字被存储为“EmployeeBlock”块定义(块表记录)中的MText。如果我们多次插入这个块,那么我们看到的都是同一个雇员的名字。我们怎样才能自定义这个块以使每次插入这个块的时候显示不同雇员的名字?这就要使用块属性的功能了。属性是存储在每一个块索引实例中的文本,并被作为实例的一部分来被显示。属性从存储在块表记录中的属性定义中继承相关的属性。
属性:
让我们来把MText实体类型改变为属性定义。在CreateEmployeeDefinition()函数中,把下面的代码替换
//文本:
MText text = new MText();
text.Contents = "Earnest Shackleton";
text.Location = center;
为
//属性定义
AttributeDefinition text = new AttributeDefinition(center, "NoName", "Name:", "Enter Name", db.Textstyle);
text.ColorIndex = 2;
试着使用TEST命令来测试一下CreateEmployeeDefinition()函数:
[CommandMethod("Test")]
public void Test()
{
CreateEmployeeDefinition();
}
你现在应该可以使用INSERT命令来插入EmployeeBlock块并对每一个实例确定一个雇员名。
当你插入Employee块时,请注意一下块插入的位置。它是正好被放置在所选点还是有些偏移?试试怎样修复它。(提示:检查块定义中的圆心)
修改CreateEmployee ()
以重用
1)
让我们来修改CreateEmployee()函数,以让它可以接收名字、薪水、部门和职位并返回创建的雇员块索引的ObjectId。函数的形式如下(你可以改变参数顺序)
public ObjectId CreateEmployee(string name, string division, double salary, Point3d pos)
2)
移除上面函数中的CommandMethod属性”CREATE”,这样它就不再是用来创建雇员的命令。
3)
修改函数的代码,这样就可以正确地设置块索引的名字、职位、部门和薪水和它的扩展字典。
· 替换
BlockReference br = new BlockReference(new Point3d(10, 10, 0), CreateEmployeeDefinition());
为
BlockReference br = new BlockReference(pos, CreateEmployeeDefinition());
· 替换
xRec.Data = new ResultBuffer(
new TypedValue((int)DxfCode.Text, "Earnest Shackleton"),
new TypedValue((int)DxfCode.Real, 72000),
new TypedValue((int)DxfCode.Text, "Sales"));
为
xRec.Data = new ResultBuffer(
new TypedValue((int)DxfCode.Text, name),
new TypedValue((int)DxfCode.Real, salary),
new TypedValue((int)DxfCode.Text, division));
4)
因为我们把雇员的名字从MText替换成块的属性定义,因此我们要创建一个相应的属性索引来显示雇员的名字。属性索引将使用属性定义的属性。
· 替换:
btr.AppendEntity(br); //加入索引到模型空间
trans.AddNewlyCreatedDBObject(br, true); //让事务处理知道
为
AttributeReference attRef = new AttributeReference();
//遍历雇员块来查找属性定义
BlockTableRecord empBtr = (BlockTableRecord)trans.GetObject(bt["EmployeeBlock"], OpenMode.ForRead);
foreach (ObjectId id in empBtr)
{
Entity ent = (Entity)trans.GetObject(id, OpenMode.ForRead, false);
//打开当前的对象!
if (ent is AttributeDefinition)
{
//设置属性为属性索引中的属性定义
AttributeDefinition attDef = ((AttributeDefinition)(ent));
attRef.SetPropertiesFrom(attDef);
attRef.Position = new Point3d(attDef.Position.X + br.Position.X, attDef.Position.Y + br.Position.Y, attDef.Position.Z + br.Position.Z);
attRef.Height = attDef.Height;
attRef.Rotation = attDef.Rotation;
attRef.Tag = attDef.Tag;
attRef.TextString = name;
}
}
//把索引加入模型空间
btr.AppendEntity(br);
//把属性索引加入到块索引
br.AttributeCollection.AppendAttribute(attRef);
//让事务处理知道
trans.AddNewlyCreatedDBObject(attRef, true);
trans.AddNewlyCreatedDBObject(br, true);
研究一下上面的代码,看看是怎样把属性定义中除显示用的文本字符串外的属性复制到属性索引的。属性被加入到块索引的属性集合中。这就是你怎样来为每一个实例自定义雇员名字。
5)
不要忘记返回雇员块索引的ObjectId,但要在提交事务处理之后才能返回:
trans.Commit();
return br.ObjectId;
6) 测试CreateEmployee。
加入一个Test命令来测试CreateEmployee:
[CommandMethod("Test")]
public void Test()
{
CreateEmployee("Earnest Shackleton", "Sales", 10000, new Point3d(10, 10, 0));
}
修改CreateDivision()
以重用
:
让我们来修改CreateDivision ()函数,以让它可以接收部门名字、经理名字并返回创建的部门经理扩展记录的ObjectId。如果部门经理已经存在,则不改变经理的名字。
1) 如果你先前在CreateEmployeeDefinition()中调用了CreateDivision(),请把它注释掉,因为我们在这里不需要创建一个部门
2)
改变CreateDivision()的形式让它接收部门和经理的名字并返回一个ObjectId。
public ObjectId CreateDivision(string division, string manager)
3) 修改上面函数的代码创建部门的名字和经理:
· 替换:
divDict = (DBDictionary)trans.GetObject(acmeDict.GetAt("Sales"), OpenMode.ForWrite);
为:
divDict = (DBDictionary)trans.GetObject(acmeDict.GetAt(division), OpenMode.ForWrite);
· 替换:
acmeDict.SetAt("Sales", divDict);
为:
acmeDict.SetAt(division, divDict);
· 替换:
mgrXRec.Data = new ResultBuffer(new TypedValue((int)DxfCode.Text, "Randolph P. Brokwell"));
为:
mgrXRec.Data = new ResultBuffer(new TypedValue((int)DxfCode.Text, manager));
不要忘了返回部门经理这个扩展记录的ObjectId,但要在提交事务处理后才返回。
trans.Commit();
//返回部门经理这个扩展记录的ObjectId
return mgrXRec.ObjectId;
现在把在中CreateEmployeeDefinition调用的CreateDivision函数给注释掉。
4) 现在通过使用TEST命令来测试调用CreateDivision函数。使用ArxDbg工具来检查条目是否已被加入到“ACME_DIVISION”下的命名对象字典。
CreateDivision("Sales", "Randolph P. Brokwell")
使用CREATE命令来创建雇员
:
我们将加入一个名为CREATE的新命令,此命令用来提示输入雇员的详细资料来创建雇员块索引。让我们来看一下这个命令是怎样使用的。
1) 让我们加入一个名为CREATE的新命令,并声明几个常用的变量和一个try-finally块。
[CommandMethod("CREATE")]
public void CreateEmployee()
{
Database db = HostApplicationServices.WorkingDatabase;
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
Transaction trans = db.TransactionManager.StartTransaction();
try
{
trans.Commit();
}
finally
{
trans.Dispose();
}
}
2) 让我们来为雇员定义可以用作为提示缺省值的常数。注意,布尔值gotPosition是用来判断用户是否已输入
职位
。
. 雇员名 - 类型 :String -缺省值 “Earnest Shackleton”
. 雇员所在部门名 - 类型:String -缺省值“Sales”
. 薪水 -类型:Double (non-negative and not zero) -缺省值10000
.
职位
-类型:Point3d -缺省值(0,0,0)
把这些常数加入到try语句后面:
string empName = "Earnest Shackleton";
string divName = "Sales";
double salary = new double();
salary = 10000;
Point3d position = new Point3d(0, 0, 0);
bool gotPosition = new bool();
//布尔值用来判断用户是否已输入
职位
gotPosition = false;
3) 现在让我们提示用户输入值。我们先使用PromptXXXOptions类来初始化要显示的提示字符串。
//提示输入每个雇员的详细资料
PromptStringOptions prName = new PromptStringOptions("Enter Employee Name <" + empName + ">");
PromptStringOptions prDiv = new PromptStringOptions("Enter Employee Division <" + divName + ">");
PromptDoubleOptions prSal = new PromptDoubleOptions("Enter Employee Salary <" + salary + ">");
PromptPointOptions prPos = new PromptPointOptions("Enter Employee Position or");
注意,提示字符串用尖括号来显示变量的值。这是AutoCAD用来提示用户这个值为缺省值。
4) 当提示用户输入
职位
时,我们也提供了一个关键字列表选项,如名字、部门和薪水。如果用户想要在选择一个点的时候改变为其它值,他可以选择那个关键字。
一个命令提示的例子如下:
Command: CREATE
Enter Employee Position or [Name/Division/Salary]:
要创建一个雇员,用户会选择一个点而其它的值被设置为缺省值。如果用户要改变其它的值,如名字,他可以输入”N”或全名”Name”,然后输入名字:
Command: CREATE
Enter Employee Position or [Name/Division/Salary]:N
Enter Employee Name <Earnest Shackleton>:
如果用户想要再次选择缺省的名字,他可以按回车键。
让我们创建用于
职位
提示的关键字列表:
//加入用于
职位
提示的关键字
prPos.Keywords.Add("Name");
prPos.Keywords.Add("Division");
prPos.Keywords.Add("Salary");
//设置提示的限制条件
prPos.AllowNone = false; //不允许没有值
5) 现在让我们声明PromptXXXResult变量来获取提示的结果:
//prompt results
PromptResult prNameRes;
PromptResult prDivRes;
PromptDoubleResult prSalRes;
PromptPointResult prPosRes;
6) 直到用户成功输入一个点后,循环才结束。如果输入错误的话,我们会提示用户并退出函数:
判断用户是否输入了关键字,我们通过检查promptresult的状态来进行:
//循环用来获取雇员的详细资料。当
职位
被输入后,循环终止。
while (!gotPosition)
{
//提示输入
职位
prPosRes = ed.GetPoint(prPos);
//取得一个点
if (prPosRes.Status == PromptStatus.OK)
{
gotPosition = true;
position = prPosRes.Value;
}
else if (prPosRes.Status == PromptStatus.Keyword) //获取一个关键字
{
//输入了Name关键字
if (prPosRes.StringResult == "Name")
{
//获取雇员名字
prName.AllowSpaces = true;
prNameRes = ed.GetString(prName);
if (prNameRes.Status != PromptStatus.OK)
{
return;
}
//如果获取雇员名字成功
if (prNameRes.StringResult != "")
{
empName = prNameRes.StringResult;
}
}
}
else
{
// 获取
职位
时发生错误
ed.WriteMessage("***Error in getting a point, exiting!!***" + "/r/n");
return;
} // 如果获取一个点
}
7) 上面的代码只提示输入名字,请加入提示输入薪水和部门的代码。
8) 完成提示输入后,我们将使用获得的值来创建雇员。
//创建雇员
CreateEmployee(empName, divName, salary, position);
9) 现在来检查部门经理是否已存在。我们通过检查NOD中部门的扩展记录中的经理名字来进行。如果检查到的是一个空字符串,那么我们会提示用户输入经理的名字。注意,通过修改CreateDivision()函数,获取经理的名字变得简单了。
string manager = "";
//创建部门
//给经理传入一个空字符串来检查它是否已存在
Xrecord depMgrXRec;
ObjectId xRecId;
xRecId = CreateDivision(divName, manager);
//打开部门经理扩展记录
depMgrXRec = (Xrecord)trans.GetObject(xRecId, OpenMode.ForRead);
TypedValue[] typedVal = depMgrXRec.Data.AsArray();
foreach (TypedValue val in typedVal)
{
string str;
str = (string)val.Value;
if (str == "")
{
//经理没有被设置,现在设置它
// 先提示输入经理的名字
ed.WriteMessage("/r/n");
PromptStringOptions prManagerName = new PromptStringOptions("No manager set for the division! Enter Manager Name");
prManagerName.AllowSpaces = true;
PromptResult prManagerNameRes = ed.GetString(prManagerName);
if (prManagerNameRes.Status != PromptStatus.OK)
{
return;
}
//设置经理的名字
depMgrXRec.Data = new ResultBuffer(new TypedValue((int)DxfCode.Text, prManagerNameRes.StringResult));
}
}
10) 测试CREATE命令
选择集:
现在让我们来创建一个命令,当用户在图形中选择一个雇员对象时,它会显示雇员的详细资料。
我们会使用上一章中创建的ListEmployee()函数在命令行中输出雇员的详细资料。
下面是你必须遵循的步骤:
调用“LISTEMPLOYEES”命令
调用Editor的GetSelection()函数来选择实体
PromptSelectionResult res = ed.GetSelection(Opts, filter);
上面的filter用来过滤选择集中的块索引。你可以创建如下的过滤列表:
TypedValue[] filList = new TypedValue[1];
filList[0] = new TypedValue((int)DxfCode.Start, "INSERT");
SelectionFilter filter = new SelectionFilter(filList);
从选择集中获取ObjectId数组:
//如果选择失败则什么也不做
if (res.Status != PromptStatus.OK)
return;
Autodesk.AutoCAD.EditorInput.SelectionSet SS = res.Value;
ObjectId[] idArray;
idArray = SS.GetObjectIds();
5. 最后,把选择集中的每个ObjectId输入到ListEmployee()函数来获取一个雇员详细资料的字符串数组。把雇员的详细资料输出到命令行。例如:
//获取saEmployeeList 数组中的所有雇员
foreach (ObjectId employeeId in idArray)
{
ListEmployee(employeeId, ref saEmployeeList);
//把雇员的详细资料输出到命令行
foreach (string employeeDetail in saEmployeeList)
{
ed.WriteMessage(employeeDetail);
}
ed.WriteMessage("----------------------" + "/r/n");
}
声明:
本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:
https://www.wpsshop.cn/w/笔触狂放9/article/detail/111767
推荐阅读
article
使用
Docker
本地安装部署
Drawio
绘图工具并实现公网访问_
docker
autocad
...
使用
Docker
本地安装部署
Drawio
绘图工具并实现公网访问_
docker
autocad
docker
autocad
...
赞
踩
article
AutoCAD
.NET
API2018
二次开发
第十五章
_
autocad2018
net开发不支持 i...
合并选择集,设置过滤器条件 选择线是红色 0图层,在过滤中使用关系运行,删除未使用的图层,复制图形对象,偏移多段线,旋转...
赞
踩
article
使用
C#对
CAD
二次开发,
获取
动态
块
的
块
名_
c#
autocad
动态
块
...
获取
动态
块
的
块
名需要
使用
AcadEntity类或其派生类的BlockName属性。但是,由于
动态
块
可以设置一个或多个匿名...
赞
踩
article
autoCAD
使用
选择
集
_cad 变量
选择
集
...
使用
选择
集
选择
集
可以由单个对象组成,也可以是一个更复杂的编组:例如特定图层的对象
集
。 在命令启动前通过pick firs...
赞
踩
article
Autodesk
Maya
2020
for
Mac(玛雅
三维动画
设计软件)_autodesk ma...
Autodesk
Maya
2020
中文版是
Autodesk
推出的
三维动画
、建模CAD图像工具
Maya
2020
系列的最新...
赞
踩
article
AutoCAD
.net 开发
SelectionFilter
Foreach
Linq
性能比较...
using System;using System.Collections.Generic;using System.L...
赞
踩
article
6基于C#的
CAD
二次开发-
对象
选择
(通过范围
选择
对象
)_
c#
autocad
选择
集...
实体
对象
的各种
选择
方式_
c#
autocad
选择
集
c#
autocad
选择
集 ...
赞
踩
article
AutoCAD
.
net
:有条件
选择
AutoCAD
实体
...
引自http://through-the-interface.typepad.com/through_the_inter...
赞
踩
article
基于C#的
AutoCAD
二次开发
之
块
操作
_
c#
autocad
操作
动态
块
...
基于C#的
AutoCAD
二次开发
之
块
操作
什么是
块
?
块
由多个在逻辑上相关的图形对象所定义的整体。
块
的优点有哪些统一作业标准...
赞
踩
article
AutoCAD
.NET
二次开发
实例(
5
) 批量获取
多段
线所有
顶点
坐标
_
如何提取
cad
多段
线里的顶...
https://mp.weixin.qq.com/s?
_
_
biz=MzA3NzI3MjgyNQ==&mid=224748...
赞
踩
article
AutoCAD
.Net 创建
多段
线
Polyline
_
appendentity
绘制
多段
线
...
以下代码展示: 往模型空间中添加一条
多段
线
Polyline
。
多段
线
有三个顶点,分别为(0, 0) (100, 100) ...
赞
踩
article
auto
cad
.
net
画多
段线
_
cad
.
net
判断点在多
段线
内-射线法...
/// ///点选直到满足条件/// /// 图形数据库/// 过滤类型,数组/// 块外/// 块内/// 点选到的图...
赞
踩
相关标签
docker
draw.io
容器
c#
开发语言
runtime
.net
数据库
cad
AutoCAD
C#
autocad.net 画多段线