第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何通過 Lambda 表達(dá)式創(chuàng)建 AutoCAD 對象并返回

如何通過 Lambda 表達(dá)式創(chuàng)建 AutoCAD 對象并返回

C#
眼眸繁星 2022-06-12 10:29:32
我是 C# 編程(和一般編程)的新手,但我正在使用 AutoDesk .NET API 進(jìn)行工作項(xiàng)目的 AutoCAD 開發(fā)。在 AutoCAD 開發(fā)中有一些重復(fù)的任務(wù),我一直在創(chuàng)建幫助方法來簡化我的代碼。為了通過 .API 在 AutoCAD 中創(chuàng)建對象(線、多段線、注釋等),程序員必須編寫一個相當(dāng)復(fù)雜的語句來訪問 AutoCAD 環(huán)境,獲取當(dāng)前圖形,獲取數(shù)據(jù)庫當(dāng)前繪圖文件,開始與數(shù)據(jù)庫的事務(wù)//do work,然后在最終提交和關(guān)閉事務(wù)之前將創(chuàng)建的實(shí)體附加到數(shù)據(jù)庫。所以我寫了下面的代碼來簡化這個任務(wù):public static void CreateObjectActionWithinTransaction(Action<Transaction, Database, BlockTable, BlockTableRecord> action){    var document = Application.DocumentManager.MdiActiveDocument;    var database = document.Database;    using (var transaction = document.TransactionManager.StartTransaction())    {        BlockTable blocktable = transaction.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;        BlockTableRecord blockTableRecord = transaction.GetObject(blocktable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;        action(transaction, database, blocktable, blockTableRecord);        transaction.Commit();    }}然后我的 Lambda 表達(dá)式創(chuàng)建一個泛型MText并為其設(shè)置一些參數(shù):public static void createMtext(Point3d location, AttachmentPoint attachmentpoint, string contents, double height, short color, bool usebackgroundmask, bool usebackgroundcolor, double backgroundscale){    CreateObjectActionWithinTransaction((transaction, database, blocktable, blocktablerecord) =>    {        MText mt = new MText();    });}最后,當(dāng)我實(shí)際在MText某處創(chuàng)建時,我可以在一行中創(chuàng)建它,并為所有參數(shù)傳入值,而無需為其編寫龐大的事務(wù)代碼:Helpers.createMtext(insertpoint, AttachmentPoint.MiddleLeft, "hello world", .08, colors.AutoCAD_Red, true, true, 1.2);所以這很棒,當(dāng)我想自己創(chuàng)建一個MText并將它放在某個地方時它可以工作。但是,在某些其他情況下MText,我想MText使用與上述相同的基本前提創(chuàng)建一個,而不是僅創(chuàng)建一個并將其放置在繪圖中,但將其作為值返回以在其他地方使用。AutoCAD 具有稱為注釋對象Multileaders,它們基本上MText就像上面一樣,但附加到一些線和一個箭頭以指向圖形中的某些內(nèi)容。在 API 中,您需要定義一個MText并將其附加到Multileader對象。但是我上面的代碼不能使用,因?yàn)樗鼪]有返回任何東西。所以我的問題歸結(jié)為,我怎樣才能創(chuàng)建一個像上面這樣的方法來創(chuàng)建一個對象,而不是僅僅創(chuàng)建那個對象,讓它返回那個對象以供另一段代碼使用?對于 Lambda 表達(dá)式的初學(xué)者,還有什么好的資源嗎?書籍、網(wǎng)站、YouTube?
查看完整描述

3 回答

?
qq_笑_17

TA貢獻(xiàn)1818條經(jīng)驗(yàn) 獲得超7個贊

對于 AutoCAD 部分:

正如 Miiir 在評論中所說,不要返回對象,而是ObjectId. 一個對象實(shí)例屬于一個事務(wù),因此如果您使用某個事務(wù)打開該對象,提交該事務(wù)并嘗試在另一個事務(wù)中使用該對象,AutoCAD 基本上只會崩潰。

使用 AutoCAD API始終遵循以下基本模式:

  1. 開始交易

  2. 創(chuàng)建新對象或使用事務(wù)來獲取現(xiàn)有對象。這可以通過使用ObjectID或 遍歷表并查找您感興趣的任何屬性(即BlockTable、BlockTableRecordLayerTable等)來完成。

  3. 對對象做一些事情。

  4. 提交或中止事務(wù)。

如果您嘗試?yán)@過第 1 步和第 2 步,則效果不會很好。所以, return ObjectID,然后使用 id 在另一個事務(wù)中獲取對象。

至于 C# 部分:

如果您希望使用委托返回值,那Action<T>不是您的朋友。Action不返回值,它只是“行動”,因此得名。如果您想使用委托返回一個值,您有 2 個選項(xiàng):

  1. 定義自定義委托類型。

  2. 使用 .NET 框架提供的通用委托Func<T1,T2,T3,T4,TResult>。

你應(yīng)該使用哪一個?在您的情況下,我可能會選擇選項(xiàng) 1,原因很簡單,因?yàn)槟拇a將更加簡潔且易于維護(hù)。我將在這個例子中使用它。使用Func的工作方式完全相同,只是你的函數(shù)簽名看起來有點(diǎn)難看。

自定義委托:

//somewhere in your code inside a namespace (rather than a class)

public delegate ObjectId MyCreateDelegate(Transaction transaction, Database db,

         BlockTable blockTable, BlockTableRecord blockTableRecord);

然后你的一般方法


public static ObjectId CreateObjectActionWithinTransaction(MyCreateDelegate createDel)

{

    ObjectId ret;

    var document = Application.DocumentManager.MdiActiveDocument;

    var database = document.Database;

    using (var transaction = document.TransactionManager.StartTransaction())

    {

        BlockTable blocktable = transaction.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;

        BlockTableRecord blockTableRecord = transaction.GetObject(blocktable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;

        //here createMtext will get called in this case, and return ObjectID

        ret = createDel(transaction, database, blocktable, blockTableRecord);

        transaction.Commit();

    }

    return ret;

}

以及使用 lambda 的具體方法:


public ObjectId createMtext(Point3d location, AttachmentPoint attachmentpoint, string contents, double height, short color, bool usebackgroundmask, bool usebackgroundcolor, double backgroundscale)

{

    //here you can return the result the general function

    return CreateObjectActionWithinTransaction((transaction, database, blocktable, blocktablerecord) =>

    {

        MText mt = new MText();

        mt.SetDatabaseDefaults();

        mt.Location = location;

        mt.Attachment = attachmentpoint;

        mt.Contents = contents;

        mt.Height = height;

        mt.Color = Color.FromColorIndex(ColorMethod.ByAci, color);

        mt.BackgroundFill = usebackgroundmask;

        mt.UseBackgroundColor = usebackgroundcolor;

        mt.BackgroundScaleFactor = backgroundscale;

        blocktablerecord.AppendEntity(mt);

        transaction.AddNewlyCreatedDBObject(mt, true);

        //make sure to get ObjectId only AFTER adding to db.

        return mt.ObjectId;

    });

}

最后,像這樣使用它


ObjectId mtId = Helpers.createMtext(insertpoint, AttachmentPoint.MiddleLeft, "hello world", .08, colors.AutoCAD_Red, true, true, 1.2);

//now use another transaction to open the object and do stuff to it.


查看完整回答
反對 回復(fù) 2022-06-12
?
斯蒂芬大帝

TA貢獻(xiàn)1827條經(jīng)驗(yàn) 獲得超8個贊

我寧愿使用從調(diào)用方法中的事務(wù)中調(diào)用的擴(kuò)展方法,而不是使用委托。


static class ExtensionMethods

{

    public static BlockTableRecord GetModelSpace(this Database db, OpenMode mode = OpenMode.ForRead)

    {

        var tr = db.TransactionManager.TopTransaction;

        if (tr == null)

            throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.NoActiveTransactions);

        return (BlockTableRecord)tr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(db), mode);

    }


    public static void Add(this BlockTableRecord btr, Entity entity)

    {

        var tr = btr.Database.TransactionManager.TopTransaction;

        if (tr == null)

            throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.NoActiveTransactions);

        btr.AppendEntity(entity);

        tr.AddNewlyCreatedDBObject(entity, true);

    }


    public static MText AddMtext(this BlockTableRecord btr, 

        Point3d location, 

        AttachmentPoint attachmentpoint, 

        string contents, 

        double height, 

        short color = 256, 

        bool usebackgroundmask = false, 

        bool usebackgroundcolor = false, 

        double backgroundscale = 1.5)

    {

        MText mt = new MText();

        mt.SetDatabaseDefaults();

        mt.Location = location;

        mt.Attachment = attachmentpoint;

        mt.Contents = contents;

        mt.Height = height;

        mt.ColorIndex = color;

        mt.BackgroundFill = usebackgroundmask;

        mt.UseBackgroundColor = usebackgroundcolor;

        mt.BackgroundScaleFactor = backgroundscale;

        btr.Add(mt);

        return mt;

    }

}

使用示例:


        public static void Test()

    {

        var doc = AcAp.DocumentManager.MdiActiveDocument;

        var db = doc.Database;

        using (var tr = db.TransactionManager.StartTransaction())

        {

            var ms = db.GetModelSpace(OpenMode.ForWrite);

            var mt = ms.AddMtext(Point3d.Origin, AttachmentPoint.TopLeft, "foobar", 2.5);

            // do what you want with 'mt'

            tr.Commit();

        }

    }


查看完整回答
反對 回復(fù) 2022-06-12
?
largeQ

TA貢獻(xiàn)2039條經(jīng)驗(yàn) 獲得超8個贊

我不熟悉 AutoCad API,但似乎“transaction.Commit()”是實(shí)際執(zhí)行將 MText 放置在模型上的操作的行。


如果是這種情況;我會做如下的事情:


public MText CreateMTextObject({parameters})

{

//code

  Return textObject

}


public PlaceTextObject({parameters})

{

  CreateTextObject(parameters).Commit()

}

這樣,您可以選擇保留文本對象以供進(jìn)一步操作,同時仍然允許選擇一次性應(yīng)用它。它也將只有一個用于制作對象的代碼塊,確保兩種方法的實(shí)現(xiàn)沒有差異


查看完整回答
反對 回復(fù) 2022-06-12
  • 3 回答
  • 0 關(guān)注
  • 134 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號