[C#] Dostęp do tablicy symboli w klasie generycznej


Rekomendowane odpowiedzi

Witam.

Zderzyłem się z programistycznym problemem niekoniecznie związanym ściśle z ZwCAD'em ale wyszedł akurat przy programie na tą platformę. Prawdopodobnie jest to problem bardziej ogólny.

Mam klasę generyczną która ma za zadanie sprawdzić czy w tablicy symboli istnieje przekazany symbol. Jeżeli nie to powinna ten symbol w tej tablicy utworzyć.

    public abstract class SymbolGenerator<TTable> : ISymbolGenerator where TTable : SymbolTable
    {
        public abstract void Generate();

        public void Generate<TSymbol>(TSymbol symbol) where TSymbol : SymbolTableRecord
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Database acDatabase = acDoc.Database;
            using (Transaction transaction = acDoc.TransactionManager.StartTransaction())
            {
                TTable symbolTable = (TTable)transaction.GetObject(GetObjectId(acDatabase, typeof(TTable)), mode: OpenMode.ForRead);

                if (!symbolTable.Has(symbol.Name))
                {
                    symbolTable.Add(symbol);								// <- tu się wywala
                    transaction.AddNewlyCreatedDBObject(symbol, true);
                    transaction.Commit();
                }
            }
        }

        private ObjectId GetObjectId(Database db, Type type)
        {
            switch(type.Name)
            {
                case "LayerTable":
                    return db.LayerTableId;
                case "TextStyleTable":
                    return db.TextStyleTableId;
                default:
                    throw new NotSupportedException();
            }
        }
    }

Jak widać klasa powinna sobie poradzić z każdą tablicą symboli. Mnie w szczególności interesują LayerTable i TextStyleTable. Po przekazaniu innej ma rzucić wyjątek. Klasa jest abstrakcyjna więc potrzebuję klasy konkretnej. Przykładowa klasa do obsługi jakiegoś stylu tekstu. Klasa dziedziczy po SymbolGenerator<TextStyleTable> jak widać oczekuje typu TextStyleTable

    public class ElevationMarkTextStyleGenerator : SymbolGenerator<TextStyleTable>, IElevationMarkTextStyleGenerator
    {
        public override void Generate()
        {
            TextStyleTableRecord style = new TextStyleTableRecord();
            style.Name = "ck_koty";
            style.FileName = "simplex.shx";
            style.XScale = 0.65;
            style.ObliquingAngle = 0;

            Generate(style);
        }
    }

Wywołanie proste:

            var generator = new ElevationMarkTextStyleGenerator();
            generator.Generate();

519183410_2018-12-1210_56_35-ZWCAD.png.8fb4ac555fa8ce3f074ecea240e1db90.png

Application does not support just-in-time (JIT)
debugging. See the end of this message for details.

************** Exception Text **************
System.Runtime.InteropServices.SEHException (0x80004005): External component has thrown an exception.
   at ZcDbSymbolTable.add(ZcDbSymbolTable* , ZcDbObjectId* , ZcDbSymbolTableRecord* )
   at ZwSoft.ZwCAD.DatabaseServices.SymbolTable.Add(SymbolTableRecord value)
   at CADKitCore.Contract.SymbolGenerator`1.Generate[TSymbol](TSymbol symbol) in D:\dev\CSharp\Workspace\CADKit\CADKit\Contract\SymbolGenerator.cs:line 21
   at CADKitElevationMarks.Model.ElevationMarkTextStyleGenerator.Generate() in D:\dev\CSharp\Workspace\CADKit\CADKitElevationMarks\Model\ElevationMarkTextStyleGenerator.cs:line 17
   at CADKitElevationMarks.Contract.BaseElevationMark..ctor(IElevationMarkConfig _config) in D:\dev\CSharp\Workspace\CADKit\CADKitElevationMarks\Contract\BaseElevationMark.cs:line 44
   at CADKitElevationMarks.Model.ArchtecturalElevationMarkPNB01025..ctor(IElevationMarkConfig config) in D:\dev\CSharp\Workspace\CADKit\CADKitElevationMarks\Model\ArchtecturalElevationMarkPNB01025.cs:line 16
   at CADKitElevationMarks.Model.ElevationMarkFactoryPNB01025.GetElevationMark(ElevationMarkType type, IElevationMarkConfig config) in D:\dev\CSharp\Workspace\CADKit\CADKitElevationMarks\Model\ElevationMarkFactoryPNB01025.cs:line 15
   at CADKitElevationMarks.Contract.ElevationMarkFactory.GetElevationMark(ElevationMarkType type) in D:\dev\CSharp\Workspace\CADKit\CADKitElevationMarks\Contract\ElevationMarkFactory.cs:line 15
   at CADKitElevationMarks.Commands.ElevationMarkArch() in D:\dev\CSharp\Workspace\CADKit\CADKitElevationMarks\Commands.cs:line 17
   at ZwSoft.ZwCAD.Runtime.CommandClass.InvokeHelper(MethodInfo mi, Object commandObject, Boolean bLispFunction)
   at ZwSoft.ZwCAD.Runtime.CommandClass.InvokeHelperWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)

Prawdę mówiąc nie wiem co robię nie tak.

Może znajdzie się ktoś bieglejszy, kto mi to wyjaśni?

 

Odnośnik do komentarza
Udostępnij na innych stronach

Tiaaaa.... proszę admina o wywalenie wątku w niebyt. Jeżeli nie to sam sobie odpowiem.

Ślepota własna. Nie odblokowałem tablicy do zapisu.

TTable symbolTable = (TTable)transaction.GetObject(GetObjectId(acDatabase, typeof(TTable)), mode: OpenMode.ForRead);	// <- tylko do odczytu
                if (!symbolTable.Has(symbol.Name))
                {
			symbolTable.UpgradeOpen();						// <- togo brakowało
                    symbolTable.Add(symbol);							
                    transaction.AddNewlyCreatedDBObject(symbol, true);
                    transaction.Commit();
                }

 

Edytowane przez perlon
Odnośnik do komentarza
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Usuń formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie