| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > C#. Переименовать layout

C#. Переименовать layout

Ответ
Поиск в этой теме
Непрочитано 16.05.2013, 19:46 #1
C#. Переименовать layout
expertlight
 
Регистрация: 16.05.2013
Сообщений: 7

Знатоки, подскажите пожалуйста, как достучаться до свойств layout'ов, а именно нужно переименовать программно. Пример - есть модель, и несколько layout'oв. Нужно переименовать их все (кроме модели). Как это сделать в рамках одной транзакции? у меня получилось переименовать только текущий layout. А как пройтись по всем layout'ам в чертеже и переименовать?

Код:
[Выделить все]
/// <summary>
        /// переименование layout
        /// </summary>
        [CommandMethod("_2")]
        public static void _2()
        {
            // получаем документ и базу
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Database acCurDb = acDoc.Database;

            using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                // Rполучаем менеджер
                LayoutManager acLayoutMgr;
                acLayoutMgr = LayoutManager.Current;

                // получаем активный текущий layout
                // В Н И М А Н И Е!!! - тут я получаю только активный layout. Не могу обратиться к менеджеру, как к массиву. Помогите!!!
                Layout acLayout;
                acLayout = acTrans.GetObject(acLayoutMgr.GetLayoutId(acLayoutMgr.CurrentLayout),
                                             OpenMode.ForWrite) as Layout;

                
                // если текущая вкладка не "модель" - переименовываем
                if (acLayout.LayoutName != "Model")
                    acLayout.LayoutName = "1";

                   
                acTrans.Commit();
            }
            
        }

Последний раз редактировалось expertlight, 16.05.2013 в 20:24. Причина: добавил код
Просмотров: 3851
 
Непрочитано 16.05.2013, 21:25
#2
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Итерация по элементам BlockTableRecord, с фильтрацией нужного контента, спасёт отца российской демократии.
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:
hwd вне форума  
 
Автор темы   Непрочитано 16.05.2013, 23:22
#3
expertlight


 
Регистрация: 16.05.2013
Сообщений: 7


BlockTableRecord сделал. Как написать цикл и обратиться к именам layout'oв? Демократия в опасности!

Код:
[Выделить все]
/// <summary>
        /// переименование layout
        /// </summary>
        [CommandMethod("_2")]
        public static void _2()
        {
            Document doc =  Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId,OpenMode.ForRead);
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId,OpenMode.ForWrite);

                foreach (/*что тут?*/)
                {
                    /*что тут?*/
                }
               
            }

        }
expertlight вне форума  
 
Непрочитано 16.05.2013, 23:55
#4
Олег (jr.)

специалист по околачиванию грушевых деревьев
 
Регистрация: 14.09.2004
Pietari, Venäjä
Сообщений: 813


Пробуй так, не тестировал просто из башки
Код:
[Выделить все]
        [CommandMethod("RenameLayout")]
        public void testRenameLayout()
        {

            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;

            Database db = doc.Database;
            try
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {

                    DBDictionary ldict = (DBDictionary)tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead);

                    LayoutManager lm = LayoutManager.Current;

                    foreach (DBDictionaryEntry dicent in ldict)
                    {
                        Layout lay = (Layout)dicent.Value.GetObject(OpenMode.ForRead);

                        //do your work in the every layout here, i.e.:

                        // open layout block table record for write
               
                        lm.CurrentLayout = lay.LayoutName;
              
                        if (lm.CurrentLayout == "Layout1")
                        {
                            lay.UpgradeOpen();
                            lay.LayoutName = "FOO";
                      
                        }

                        else continue;

                    }
                    tr.Commit();
                }
            }
            catch(Autodesk.AutoCAD.Runtime.Exception ex)
            {
                Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(ex.Message + "\n" + ex.StackTrace);
            }

        }
Олег (jr.) вне форума  
 
Непрочитано 17.05.2013, 08:39
#5
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


@expertlight,

Действительно, добраться до информации о слоях можно через DBDictionary, как показал Олег (jr.), но сделать это можно и через BlockTableRecord, как я уже упоминал (код ниже). Однако в своём коде Олег (jr.), производит и визуальное переключение между Layouts, что может несколько раздражать пользователя (например меня такое мерцание несколько напрягает). Полагаю, что так он просто показал тебе способ переключения между листами.

Итак, способ, путём итерации по BlockTableRecord:
Код:
[Выделить все]
using cad = Autodesk.AutoCAD.ApplicationServices.Application;
using App = Autodesk.AutoCAD.ApplicationServices;
using Rtm = Autodesk.AutoCAD.Runtime;
using Db = Autodesk.AutoCAD.DatabaseServices;
using Ed = Autodesk.AutoCAD.EditorInput;
...
[Rtm.CommandMethod("RenameAllLayout")]
public void testRenameAllLayout() {
    App.Document doc = cad.DocumentManager.MdiActiveDocument;
    Db.Database db = doc.Database;
    Ed.Editor ed = doc.Editor;

    using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
        Db.BlockTable bt = tr.GetObject(db.BlockTableId, Db.OpenMode.ForRead)
            as Db.BlockTable;
        foreach (Db.ObjectId id in bt) {
            Db.BlockTableRecord btr = tr.GetObject(id, Db.OpenMode.ForRead)
                as Db.BlockTableRecord;
            if (btr.IsLayout) {
                Db.Layout layout = tr.GetObject(btr.LayoutId, Db.OpenMode.ForWrite)
                    as Db.Layout;
                if (!layout.LayoutName.Equals("Model"))
                    layout.LayoutName += " (renamed)";
            }
        }
        tr.Commit();
    }
}
...
В коде Олег (jr.) я бы внёс небольшие изменения, дабы визуально не переключаться на каждый лист (избавиться от мерцания), случайно не создавать исключение при попытке переименовать "Model" в цикле, а так же изменил способ переименования (чтобы показать альтернативный):
Код:
[Выделить все]
using cad = Autodesk.AutoCAD.ApplicationServices.Application;
using App = Autodesk.AutoCAD.ApplicationServices;
using Rtm = Autodesk.AutoCAD.Runtime;
using Db = Autodesk.AutoCAD.DatabaseServices;
using Ed = Autodesk.AutoCAD.EditorInput;
...
[Rtm.CommandMethod("RenameLayout")]
public void testRenameLayout() {
    App.Document doc = cad.DocumentManager.MdiActiveDocument;
    Db.Database db = doc.Database;
    try {
        using (Db.Transaction tr = db.TransactionManager.StartTransaction()) {
            Db.DBDictionary ldict = (Db.DBDictionary) tr.GetObject(db.LayoutDictionaryId,
                Db.OpenMode.ForRead);
            Db.LayoutManager lm = Db.LayoutManager.Current;
            foreach (Db.DBDictionaryEntry dicent in ldict) {
                Db.Layout lay = (Db.Layout) dicent.Value.GetObject(Db.OpenMode.ForRead);
                if (!lay.LayoutName.Equals("Model")) {
                    lay.UpgradeOpen();
                    lm.RenameLayout(lay.LayoutName, lay.LayoutName + " (renamed2)");
                }
            }
            tr.Commit();
        }
    }
    catch (Rtm.Exception ex) {
        cad.ShowAlertDialog(ex.Message + "\n" + ex.StackTrace);
    }
}
...
@expertlight,

Глядя на твой последний "код", складывается устойчивое ощущение, что документацию и поиск ты игнорируешь в принципе, а решение пытаешься получить банальным угадыванием, даже не вникая в то, что написал в своём коде (а написана там откровенная чушь).

При желании ответ по теме весьма быстро находится самостоятельно. Из каких соображений не смотришь в официальную документацию (ObjectARX SDK)? Возьми за привычку юзать поиск в Google. Наиболее полезные ресурсы по теме .NET программирования в AutoCAD:
1. тынц.
2. тынц.
3. тынц.
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:

Последний раз редактировалось hwd, 17.05.2013 в 11:56. Причина: Исправил сообщение.
hwd вне форума  
 
Автор темы   Непрочитано 17.05.2013, 22:18
#6
expertlight


 
Регистрация: 16.05.2013
Сообщений: 7


Я пока плохо понимаю иерархию объектов. hwd, ваш способ именно то, что я хотел. В AutoCAD .NET Developer's Guide не нашел, как работать с layout'ами. Теперь начну изучение с иерархии объектов. Олег (jr.), спасибо тоже за ваше решение!
expertlight вне форума  
 
Непрочитано 19.05.2013, 13:43
#7
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от expertlight Посмотреть сообщение
В AutoCAD .NET Developer's Guide не нашел, как работать с layout'ами.
тынц.
__________________
Надеюсь, ты не социальный овощ? Это определяется делами! :welcome:
hwd вне форума  
 
Непрочитано 19.05.2013, 17:13
#8
Олег (jr.)

специалист по околачиванию грушевых деревьев
 
Регистрация: 14.09.2004
Pietari, Venäjä
Сообщений: 813


Цитата:
Сообщение от expertlight Посмотреть сообщение
Олег (jr.), спасибо тоже за ваше решение!
Пожалуйста, можно попробовать такой код тожеЮ тестировал на А2010:
Код:
[Выделить все]
        // public class LayoutTools
        // {
        // declare layout names outside of method, keep them empty:
        string oldname = ""; string newname = "";
        [CommandMethod("lre")]
        public void testLayoutsRename()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = HostApplicationServices.WorkingDatabase;
            Editor ed = doc.Editor;
            Transaction tr = db.TransactionManager.StartTransaction();

            SortedList<string, string> ltnames = new SortedList<string, string>();
            ltnames.Add("Layout1", "General");
            ltnames.Add("Layout2", "Floor Plan 1");
            ltnames.Add("Layout3", "Floor Plan 2");
            ltnames.Add("Layout4", "Floor Plan 3");//   ETC ...
            LayoutManager lm = LayoutManager.Current;
            ObjectId lyid = ObjectId.Null;
            try
            {
                using (tr)
                {
                    foreach (KeyValuePair<string, string> kvp in ltnames)
                    {
                        oldname = kvp.Key; newname = kvp.Value;
                        lyid = lm.GetLayoutId(oldname);

                        if (lm.GetLayoutId(oldname) != ObjectId.Null)
                        {
                            Layout lt = tr.GetObject(lyid, OpenMode.ForWrite) as Layout;

                            lm.LayoutRenamed += new LayoutRenamedEventHandler(lm_LayoutRenamed);
                            lm.LayoutToBeRenamed += new LayoutRenamedEventHandler(lm_LayoutToBeRenamed);
                            lt.LayoutName = newname;
                        }
                    }
                    tr.Commit();
                    ed.Regen();
                }
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
                    "\nRerror Reason: {0}\n", ex.ErrorStatus);
                return;
            }

        }

        private void lm_LayoutRenamed(object sender, LayoutRenamedEventArgs e)
        {
            string newmame = "";
            try
            {
                newmame = e.NewName;
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
                    "\nInvalid layout name: {0}\n{1}", e.NewName, ex.ErrorStatus);
                return;
            }

        }
        private void lm_LayoutToBeRenamed(object sender, LayoutRenamedEventArgs e)
        {
            try
            {
                SymbolUtilityServices.ValidateSymbolName(oldname, false);
            }
            catch (Autodesk.AutoCAD.Runtime.Exception ex)
            {
                Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
                    "\nInvalid layout name: {0}\n{1}", e.NewName, ex.ErrorStatus);
                return;
            }

        }

    //}// end of class
Олег (jr.) вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > C#. Переименовать layout

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
LISP. Копирование, сортировка, переименование листов (layout) VVA Готовые программы 96 08.12.2023 14:11
C# .net Создание Layout для чертежей, оформленных в модели bargool Готовые программы 649 18.11.2023 23:13
Вставка блока во все layout serg01 Программирование 2 30.09.2009 08:59
Программная печать из листа с учетом его параметров. TheBuTeK Программирование 27 08.08.2008 21:58
Можно ли переименовать Layout? ===AAA=== Программирование 10 16.09.2005 19:08