block 和 reference 标签 里的type属性

本文介绍了Magento中如何通过布局文件的URI属性实例化块对象。详细解析了如何根据URI的第一部分在全局配置中查找基本类名,以及如何结合URI第二部分生成具体的类名。
实例化块对象

在布局文件中,<block />和<reference />标签有一个“type”属性,这个属性其实是一个URI
<block type="page/html" ...
<block type="page/template_links"
Magento就是通过这个URI是用来查找块对应的类名。这个URI分为两部分,第一部分“page”是用来在全局配置中查找一个基本类名,第二部分“html”或者“template_link”将被添加到基本类名后面生成一个具体的将被实例化的类名。
我们以“page/html”为例。首先Magento在全局配置中找到节
/global/blocks/page
有以下内容:

<page>
    <class>
        Mage_Page_Block
    </class>
</page>

这里我们拿到了一个基本类名“Mage_Page_Block”,然后添加URI的第二部分“html”到基本类名后面,我们就得到最终的块对象的类名 “Mage_Page_Block_Html”。块的类名在Magento中被称为“分组类名”(Grouped Class Names),这些类都用相似的方法被实例化。
using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using FengJing.Services.PlantLibModule; using FengJing.Views.OtherView; using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using Application = Autodesk.AutoCAD.ApplicationServices.Application; using Exception = Autodesk.AutoCAD.Runtime.Exception; [assembly: CommandClass(typeof(FengJing.CADModule.PlantManager))] namespace FengJing.CADModule { public class PlantManager { private static string _selectedPlantName = null; private const string RegAppName = "MyPlantApp"; // 属性定义与标签的映射 private static readonly Dictionary<string, string> AttributeTags = new Dictionary<string, string> { {"名称", "PLANT_NAME"}, {"类型", "PLANT_TYPE"}, {"高度(m)", "PLANT_HEIGHT"}, {"冠幅(cm)", "PLANT_CROWN"}, {"胸径(cm)", "PLANT_DIAMETER"}, {"单位", "PLANT_UNIT"}, {"观赏价值", "PLANT_ORNAMENTAL"}, {"色叶期", "PLANT_COLOR_PERIOD"}, {"颜色", "PLANT_COLOR"}, {"耐湿耐旱性", "PLANT_TOLERANCE"}, {"海绵类", "PLANT_SPONGE"}, {"生长习性", "PLANT_HABIT"}, {"种植密度(株/㎡)", "PLANT_DENSITY"}, {"信息价(元)", "PLANT_PRICE"} }; [CommandMethod("INSERT_PLANT", CommandFlags.Modal)] public void InsertPlantBlock() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; RegisterRegAppName(db); try { plantService plantService = new plantService(); List<Plant> allPlants = plantService.GetAllPlants(); if (allPlants == null || allPlants.Count == 0) { ed.WriteMessage("\n数据库中没有苗木数据!"); return; } _selectedPlantName = null; Application.ShowModelessWindow(new PlantList(allPlants, this)); while (_selectedPlantName == null) { System.Windows.Forms.Application.DoEvents(); System.Threading.Thread.Sleep(100); if (!Application.MainWindow.Visible) return; } string plantName = _selectedPlantName; PromptPointResult ppr = ed.GetPoint("\n指定苗木插入点: "); if (ppr.Status != PromptStatus.OK) return; using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTable blockTable = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; string blockName = GenerateBlockName(plantName); if (!blockTable.Has(blockName)) { ed.WriteMessage($"\n错误:未找到名为 {blockName} 的块定义,请在CAD中预先创建!"); return; } BlockReference blockRef = InsertPlantReference(tr, db, blockName, ppr.Value); Plant plantForBinding = plantService.GetPlantByName(plantName); if (plantForBinding != null) { BlockReference blockRefForWrite = (BlockReference)tr.GetObject(blockRef.ObjectId, OpenMode.ForWrite); BindPlantAttributes(tr, blockRefForWrite, plantForBinding); ed.WriteMessage($"\n苗木 '{plantName}' 属性已绑定到块!"); } tr.Commit(); ed.WriteMessage($"\n苗木 '{plantName}' 插入成功!"); } } catch (Exception ex) { ed.WriteMessage($"\n错误: {ex.Message}"); } } [CommandMethod("BIND_PLANT", CommandFlags.Modal)] public void BindPlantToBlock() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; RegisterRegAppName(db); try { PromptEntityOptions opts = new PromptEntityOptions("\n选择要绑定苗木属性的块: "); opts.SetRejectMessage("\n请选择一个块参照."); opts.AddAllowedClass(typeof(BlockReference), false); PromptEntityResult per = ed.GetEntity(opts); if (per.Status != PromptStatus.OK) return; plantService plantService = new plantService(); List<Plant> allPlants = plantService.GetAllPlants(); if (allPlants == null || allPlants.Count == 0) { ed.WriteMessage("\n数据库中没有苗木数据!"); return; } _selectedPlantName = null; Application.ShowModelessWindow(new PlantList(allPlants, this)); while (_selectedPlantName == null) { System.Windows.Forms.Application.DoEvents(); System.Threading.Thread.Sleep(100); if (!Application.MainWindow.Visible) return; } string plantName = _selectedPlantName; Plant selectedPlant = plantService.GetPlantByName(plantName); if (selectedPlant == null) { ed.WriteMessage($"\n未找到苗木: {plantName}"); return; } using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockReference blockRef = tr.GetObject(per.ObjectId, OpenMode.ForWrite) as BlockReference; BindPlantAttributes(tr, blockRef, selectedPlant); tr.Commit(); ed.WriteMessage($"\n成功绑定苗木属性到块: {plantName}"); } } catch (Exception ex) { ed.WriteMessage($"\n错误: {ex.Message}"); } } // 绑定属性到块属性 private void BindPlantAttributes(Transaction tr, BlockReference blockRef, Plant plant) { // 1. 绑定到块属性 if (blockRef.AttributeCollection.Count > 0) { foreach (ObjectId attId in blockRef.AttributeCollection) { AttributeReference attRef = tr.GetObject(attId, OpenMode.ForWrite) as AttributeReference; if (attRef != null && AttributeTags.ContainsValue(attRef.Tag)) { var mapping = AttributeTags.FirstOrDefault(x => x.Value == attRef.Tag); if (!string.IsNullOrEmpty(mapping.Key)) { attRef.TextString = GetPlantPropertyValue(plant, mapping.Key); } } } } // 2. 同时保留XData以备其他用途 ResultBuffer rb = new ResultBuffer(); rb.Add(new TypedValue((int)DxfCode.ExtendedDataRegAppName, RegAppName)); foreach (var prop in AttributeTags) { rb.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, prop.Key)); rb.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, GetPlantPropertyValue(plant, prop.Key))); } blockRef.XData = rb; } // 获取苗木属性值 private string GetPlantPropertyValue(Plant plant, string propertyName) { switch (propertyName) { case "名称": return plant.Name; case "类型": return plant.Type?.Name ?? "未知"; case "高度(m)": return plant.Height.ToString("0.0"); case "冠幅(cm)": return plant.CrownWidth.ToString(); case "胸径(cm)": return plant.Diameter.ToString(); case "单位": return plant.Unit?.UnitName ?? ""; case "观赏价值": return plant.OrnamentalValue?.OrnamentalValueName ?? ""; case "色叶期": return plant.ColorPeriod?.ColorPeriodName ?? ""; case "颜色": return plant.Color?.ColorName ?? ""; case "耐湿耐旱性": return plant.WetDroughtTolerance; case "海绵类": return plant.IsSpongePlant.ToString(); case "生长习性": return plant.Habit; case "种植密度(株/㎡)": return plant.PlantingDensity.ToString(); case "信息价(元)": return plant.Price.ToString(); default: return string.Empty; } } public void SetSelectedPlant(string plantName) { _selectedPlantName = plantName; } private string GenerateBlockName(string plantName) { return plantName .Replace(" ", "_") .Replace("/", "_") .Replace("\\", "_") .Replace("*", "") .ToUpper(); } private BlockReference InsertPlantReference( Transaction tr, Database db, string blockName, Point3d insertionPoint) { BlockTable blockTable = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; ObjectId blockId = blockTable[blockName]; BlockTableRecord modelSpace = tr.GetObject( SymbolUtilityServices.GetBlockModelSpaceId(db), OpenMode.ForWrite) as BlockTableRecord; BlockReference plantRef = new BlockReference(insertionPoint, blockId); modelSpace.AppendEntity(plantRef); tr.AddNewlyCreatedDBObject(plantRef, true); // 创建属性引用 CreateAttributeReferences(tr, plantRef); return plantRef; } // 创建属性引用 private void CreateAttributeReferences(Transaction tr, BlockReference blockRef) { BlockTableRecord btr = tr.GetObject(blockRef.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord; foreach (ObjectId id in btr) { if (id.ObjectClass == RXClass.GetClass(typeof(AttributeDefinition))) { AttributeDefinition ad = tr.GetObject(id, OpenMode.ForRead) as AttributeDefinition; if (ad != null && !ad.Constant) { AttributeReference ar = new AttributeReference(); ar.SetAttributeFromBlock(ad, blockRef.BlockTransform); ar.Position = ad.Position.TransformBy(blockRef.BlockTransform); ar.TextString = ad.TextString; ar.Layer = blockRef.Layer; ar.ColorIndex = blockRef.ColorIndex; blockRef.AttributeCollection.AppendAttribute(ar); tr.AddNewlyCreatedDBObject(ar, true); } } } } private void RegisterRegAppName(Database db) { using (Transaction tr = db.TransactionManager.StartTransaction()) { RegAppTable regAppTable = tr.GetObject(db.RegAppTableId, OpenMode.ForWrite) as RegAppTable; if (!regAppTable.Has(RegAppName)) { RegAppTableRecord record = new RegAppTableRecord(); record.Name = RegAppName; regAppTable.Add(record); tr.AddNewlyCreatedDBObject(record, true); } tr.Commit(); } } } } 整体代码实现还是有问题,我的需求如下: 1、在CAD界面先创建图形,然后把这些图形添加到块 2、块添加完成之后,我需要输入命令选择苗木把苗木属性绑定到块的属性 3、绑定完成之后不需要输入其他命令,点击块,查看块的特性然后显示添加的苗木信息
最新发布
07-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值