.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

vb.net generic list

12 REPLIES 12
Reply
Message 1 of 13
kcimos
1659 Views, 12 Replies

vb.net generic list

I created a class with about 40 properties in it

In another class I have created of generic list of the above class (lets just call it "A" here, & the list "Alist")

It seemed to me that the best way of populating my list would be to create a temporary variable of type "A" (let's call it "tempA"), do a wide variety of things to set the various properties of tempA, which involves creating a bunch of different objects (layer table records for example), and then adding tempA to Alist as follows:

 

Alist.add(tempA)

 

the problem with this is that every item in  my list ends up being a reference to tempA,

 

so Instead of using tempA, I just directly set the current list member by keeping track of my count (which now starts getting into the extra code required that I'm trying to avoid by using lists in the first place). But this only "works" if I set the property to an actual value such as TRUE, or 15, etc, otherwise all list memebers still reference the same object such as a layertablerecord. So in a list of layernames that should be "a", "b",..."z", I end up with "z","z",..."z".

 

I do not want to create constructors for my class, & end up with :

 

Alist.add(layouttype, layoutname,layername,ison,isfrozen, etc, etc & 35 more items would go in this series)

 

is there a way to force or convert the referenced data to be byval?

 

should I just use an array instead?

 

why are lists byref to begin with? what good does that do?

 

12 REPLIES 12
Message 2 of 13
andrewpuller3811
in reply to: kcimos

I'm only learning myself but I was having the same problem adding many objects to a list and ended up using the following -

 

In a seperate sub/function I had

 

Sub AddAtoList()

 

   tempA = New A

 

   <code to populate tempA properties>

 

   Alist.Add(tempA)

 

   tempA = Nothing

 

End Sub

 


I'm sure one of the more experienced people can explain far better than me.



If a post provides a fix for your issue, click on "Accept as Solution" to help other users find solutions to problems they might have that are similar to yours.

Andrew Puller
Maitland, NSW, Australia
Windows 10 Enterprise 64bit
Intel core i7 11800 @ 2.30 GHz with 32GB Ram
Civil 3d 2021
Message 3 of 13
_gile
in reply to: kcimos

Hi,

It seems that you are missing some .NET/OOP basics.

All classes (except string) are reference type, on the other hand, structures are value type.

Both List and Array are reference type so using an array instead of a list won't solve your problem.

If I understand what you're tying to do: populate a list of a 'A' type using the default (without arguments) 'A' constructor to create instances of 'A' (I suppose you set each 'A' instance properties from the class where the list is build).

so, IMO your problem is due to the way you create each 'A' instance. In the class where you populate the list, you need to explicitly create a New instance of 'A' for each object

Here's a little sample (not related to AutoCAD):

C#

using System;
using System.Collections.Generic;

namespace GenericListSample
{
    class Program
    {
        static void Main()
        {
            List<A> Alist = new List<A>();

            A tempA = new A();
            tempA.Name = "foo";
            tempA.Index = 1;
            tempA.Date = new DateTime(2012, 11, 10);
            tempA.Position = new double[2] { 0.0, 0.0 };
            Alist.Add(tempA);

            tempA = new A();
            tempA.Name = "bar";
            tempA.Index = 2;
            tempA.Date = new DateTime(2012, 11, 12);
            tempA.Position = new double[2] { 10.0, 20.0 };
            Alist.Add(tempA);

            tempA = new A();
            tempA.Name = "baz";
            tempA.Index = 3;
            tempA.Date = new DateTime(2012, 11, 18);
            tempA.Position = new double[2] { 50.0, 30.0 };
            Alist.Add(tempA);

            foreach (A a in Alist)
            {
                Console.WriteLine("Name: {0}, Index: {1}, Date: {2}, Position: {3}, {4}",
                    a.Name, a.Index, a.Date, a.Position[0], a.Position[1]);
            }
        }
    }

    class A
    {
        public string Name { get; set; } // value type
        public int Index { get; set; } // value type
        public DateTime Date { get; set; } // reference type
        public double[] Position { get; set; } // reference type
    }
}

 

VB

Imports System
Imports System.Collections.Generic

Namespace GenericListSample
    Class Program
        Public Shared Sub Main()
            Dim Alist As New List(Of A)()

            Dim tempA As New A()
            tempA.Name = "foo"
            tempA.Index = 1
            tempA.TheDate = New DateTime(2012, 11, 10)
            tempA.Position = New Double(1) {0.0, 0.0}
            Alist.Add(tempA)

            tempA = New A()
            tempA.Name = "bar"
            tempA.Index = 2
            tempA.TheDate = New DateTime(2012, 11, 12)
            tempA.Position = New Double(1) {10.0, 20.0}
            Alist.Add(tempA)

            tempA = New A()
            tempA.Name = "baz"
            tempA.Index = 3
            tempA.TheDate = New DateTime(2012, 11, 18)
            tempA.Position = New Double(1) {50.0, 30.0}
            Alist.Add(tempA)

            For Each a As A In Alist
                Console.WriteLine("Name: {0}, Index: {1}, Date: {2}, Position: {3}, {4}", _
                                  a.Name, a.Index, a.TheDate, a.Position(0), a.Position(1))
            Next
        End Sub
    End Class

    Class A
        Private m_Name As String ' value type
        Private m_Index As Integer ' value type
        Private m_Date As DateTime ' reference type
        Private m_Position As Double() ' reference type

        Public Property Name() As String
            Get
                Return m_Name
            End Get
            Set(value As String)
                m_Name = value
            End Set
        End Property

        Public Property Index() As Integer
            Get
                Return m_Index
            End Get
            Set(value As Integer)
                m_Index = value
            End Set
        End Property

        Public Property TheDate() As DateTime
            Get
                Return m_Date
            End Get
            Set(value As DateTime)
                m_Date = Value
            End Set
        End Property

        Public Property Position() As Double()
            Get
                Return m_Position
            End Get
            Set(value As Double())
                m_Position = value
            End Set
        End Property

    End Class

End Namespace

 

Another way is to make 'A' type a structure rather than a class. As a structure is  a value type, a new instance will be implictly created.

Here's the same sample as upper using a structure:

 

C#

using System;
using System.Collections.Generic;

namespace GenericListSample
{
    class Program
    {
        static void Main()
        {
            List<B> Blist = new List<B>();

            B tempB = new B();
            tempB.Name = "foo";
            tempB.Index = 1;
            tempB.Date = new DateTime(2012, 11, 10);
            tempB.Position = new double[2] { 0.0, 0.0 };
            Blist.Add(tempB);

            tempB.Name = "bar";
            tempB.Index = 2;
            tempB.Date = new DateTime(2012, 11, 12);
            tempB.Position = new double[2] { 10.0, 20.0 };
            Blist.Add(tempB);

            tempB.Name = "baz";
            tempB.Index = 3;
            tempB.Date = new DateTime(2012, 11, 18);
            tempB.Position = new double[2] { 50.0, 30.0 };
            Blist.Add(tempB);

            foreach (B a in Blist)
            {
                Console.WriteLine("Name: {0}, Index: {1}, Date: {2}, Position: {3}, {4}",
                    a.Name, a.Index, a.Date, a.Position[0], a.Position[1]);
            }
        }
    }

    struct B
    {
        public string Name { get; set; } // value type
        public int Index { get; set; } // value type
        public DateTime Date { get; set; } // reference type
        public double[] Position { get; set; } // reference type
    }
}

 

VB

Imports System
Imports System.Collections.Generic

Namespace GenericListSample
    Class Program
        Public Shared Sub Main()
            Dim Blist As New List(Of B)()

            Dim tempB As New B()
            tempB.Name = "foo"
            tempB.Index = 1
            tempB.TheDate = New DateTime(2012, 11, 10)
            tempB.Position = New Double(1) {0.0, 0.0}
            Blist.Add(tempB)

            tempB.Name = "bar"
            tempB.Index = 2
            tempB.TheDate = New DateTime(2012, 11, 12)
            tempB.Position = New Double(1) {10.0, 20.0}
            Blist.Add(tempB)

            tempB.Name = "baz"
            tempB.Index = 3
            tempB.TheDate = New DateTime(2012, 11, 18)
            tempB.Position = New Double(1) {50.0, 30.0}
            Blist.Add(tempB)

            For Each a As B In Blist
                Console.WriteLine("Name: {0}, Index: {1}, Date: {2}, Position: {3}, {4}", a.Name, a.Index, a.TheDate, a.Position(0), a.Position(1))
            Next
        End Sub
    End Class

    Structure B
        Private m_Name As String ' value type
        Private m_Index As Integer ' value type
        Private m_Date As DateTime ' reference type
        Private m_Position As Double() ' reference type

        Public Property Name() As String
            Get
                Return m_Name
            End Get
            Set(value As String)
                m_Name = value
            End Set
        End Property

        Public Property Index() As Integer
            Get
                Return m_Index
            End Get
            Set(value As Integer)
                m_Index = value
            End Set
        End Property

        Public Property TheDate() As DateTime
            Get
                Return m_Date
            End Get
            Set(value As DateTime)
                m_Date = value
            End Set
        End Property

        Public Property Position() As Double()
            Get
                Return m_Position
            End Get
            Set(value As Double())
                m_Position = value
            End Set
        End Property
    End Structure

End Namespace

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 4 of 13
Hallex
in reply to: andrewpuller3811

See here for more http://msdn.microsoft.com/en-us/library/6sh2ey19(v=vs.90).aspx

Generic classes encapsulate operations that are not specific to a particular data type.

The most common use for generic classes is with collections like linked lists, hash tables,

 stacks, queues, trees and so on where operations such as adding and removing items

 from the collection are performed in much the same way regardless of the type of data

being stored. See here for more

http://msdn.microsoft.com/en-us/library/6sh2ey19(v=vs.90).aspx

 

You can also to create a list of your classes like this

: List<List<MyClass>> master= new List<List<MyClass>>();

to add members to list see methods Add, AddRange,CopyTo etc:

http://msdn.microsoft.com/en-us/library/d9hw1as6(v=vs.90).aspx

 

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 5 of 13
kcimos
in reply to: kcimos

_gile,

let me see if I got this striaght:

in your example a new instance of the class is created (3 times) with

Dim tempA = New A()

&

tempA = New A()

& the properties are filled in after each is created.

& then it it is added to the list via

Alist.Add(tempA)

 

wait a minute, I swear I tried something like that already, except I was using a loop to iterate through all the layers in a  drawing. I had something like this

 

 

for each thingThing as thing in aThingFullOfThings

            tempA = New A
            tempA.Name = "foo"
            tempA.Index = 1
            tempA.TheDate = New DateTime(2012, 11, 10)
            tempA.Position = New Double(1) {0.0, 0.0}
            Alist.Add(tempA)
next

 but I had  A & Alist declared  as class properties, with shared variables tied to the properties, one of which was a new list (of A).

 

could that be causing my problem?

 

I'm going to experiment a bit more. I don't need A & AList to be properties actually. I had copied what I did for another project which was my first atttempt using lists & it is unfinished so I never ran into my current problems

 

 

Message 6 of 13
kcimos
in reply to: kcimos

actually, I want to keep my properties in my main procedure class, because they would still be useful here, but manditory in another project, so I really need to figure this out.

 

I really don't see any difference between what I'm doing & your example, except for the fact that I'm trying to assign properties of other objects to my list member's properties. If I assign a particular string or an integer or whatever everything works as I expected it too.

 

To me it just seems like I need to somehow break the link between the list members' properties & the object's property that I'm extracting the information from such as LayerTableRecord.Name.

 

so to try to do this I created a temp variable of class A, & assigned values to its properties such as

tempA.Layername =LayerTableRecord.Name

then added tempA to Alist, then set tempA to nothing. Then in the next iteration of reading the layers created a new variable called tempA, (tempA = New A) which to me seems like it should be a new variable called tempA that has nothing to do with the first or 200th variable that was also called TempA. The results of my list is that all memeber's properties reflect the last TempA that was created instead of being unique.

 

here is my actual code:

 

Public Class FullLayerData

    Private strLayoutName As String
    Private strSpaceName As String

    Private strLayerName As String
    Private strColorName As String
    Private strLinetypeName As String
    Private strLineweightName As String
    Private strPlotStyleName As String

    Private strVpLayerColorName As String
    Private strVpLinetypeName As String
    Private strVpLineweightName As String
    Private strVpPlotStyleName As String

    Private booIsLayout As Boolean
    Private booIsModelSpace As Boolean
    Private booLayerON As Boolean
    Private booLayerFrozen As Boolean
    Private booLayerVpFrozen As Boolean
    Private booLayerNoPlot As Boolean
    Private booLayerNewFrozen As Boolean

    Private booIsColorVpOverridden As Boolean
    Private booIsLinetypVpOverridden As Boolean
    Private booIsLineweightVpOverridden As Boolean
    Private booIsPlotStyleVpOverridden As Boolean

    Private iVpNumber As Integer

    Private colLayerColor As Autodesk.AutoCAD.Colors.Color
    Private colVpLayerColor As Autodesk.AutoCAD.Colors.Color


    Public Property LayoutName() As String

        Get

            Return strLayoutName

        End Get
        Set(ByVal value As String)

            strLayoutName = value

        End Set
    End Property

    Public Property SpaceName() As String

        Get

            Return strSpaceName

        End Get
        Set(ByVal value As String)

            strSpaceName = value

        End Set
    End Property

    Public Property LayerName() As String

        Get

            Return strLayerName

        End Get
        Set(ByVal value As String)

            strLayerName = value

        End Set
    End Property

    Public Property ColorName() As String

        Get

            Return strColorName

        End Get
        Set(ByVal value As String)

            strColorName = value

        End Set
    End Property

    Public Property LinetypeName() As String

        Get

            Return strLinetypeName

        End Get
        Set(ByVal value As String)

            strLinetypeName = value

        End Set
    End Property

    Public Property LineweightName() As String

        Get

            Return strLineweightName

        End Get
        Set(ByVal value As String)

            strLineweightName = value

        End Set
    End Property

    Public Property PlotStyleName() As String

        Get

            Return strPlotStyleName

        End Get
        Set(ByVal value As String)

            strPlotStyleName = value

        End Set
    End Property

    Public Property VpLayerColorName() As String

        Get

            Return strVpLayerColorName

        End Get
        Set(ByVal value As String)

            strVpLayerColorName = value

        End Set
    End Property

    Public Property VpLinetypeName() As String

        Get

            Return strVpLinetypeName

        End Get
        Set(ByVal value As String)

            strVpLinetypeName = value

        End Set
    End Property

    Public Property VpLineweightName() As String

        Get

            Return strVpLineweightName

        End Get
        Set(ByVal value As String)

            strVpLineweightName = value

        End Set
    End Property

    Public Property VpPlotStyleName() As String

        Get

            Return strVpPlotStyleName

        End Get
        Set(ByVal value As String)

            strVpPlotStyleName = value

        End Set
    End Property





    Public Property IsLayout() As Boolean

        Get

            Return booIsLayout

        End Get
        Set(ByVal value As Boolean)

            booIsLayout = value

        End Set
    End Property
   
    Public Property IsModelSpace() As Boolean

        Get

            Return booIsModelSpace

        End Get
        Set(ByVal value As Boolean)

            booIsModelSpace = value

        End Set
    End Property

    Public Property LayerON() As Boolean

        Get

            Return booLayerON

        End Get
        Set(ByVal value As Boolean)

            booLayerON = value

        End Set
    End Property

    Public Property LayerFrozen() As Boolean

        Get

            Return booLayerFrozen

        End Get
        Set(ByVal value As Boolean)

            booLayerFrozen = value

        End Set
    End Property

    Public Property LayerVpFrozen() As Boolean

        Get

            Return booLayerVpFrozen

        End Get
        Set(ByVal value As Boolean)

            booLayerVpFrozen = value

        End Set
    End Property

    Public Property LayerNoPlot() As Boolean

        Get

            Return booLayerNoPlot

        End Get
        Set(ByVal value As Boolean)

            booLayerNoPlot = value

        End Set
    End Property

    Public Property LayerNewFrozen() As Boolean

        Get

            Return booLayerNewFrozen

        End Get
        Set(ByVal value As Boolean)

            booLayerNewFrozen = value

        End Set
    End Property

    Public Property IsColorVpOverridden() As Boolean

        Get

            Return booIsColorVpOverridden

        End Get
        Set(ByVal value As Boolean)

            booIsColorVpOverridden = value

        End Set
    End Property

    Public Property IsLinetypVpOverridden() As Boolean

        Get

            Return booIsLinetypVpOverridden

        End Get
        Set(ByVal value As Boolean)

            booIsLinetypVpOverridden = value

        End Set
    End Property

    Public Property IsLineweightVpOverridden() As Boolean

        Get

            Return booIsLineweightVpOverridden

        End Get
        Set(ByVal value As Boolean)

            booIsLineweightVpOverridden = value

        End Set
    End Property


    Public Property IsPlotStyleVpOverridden() As Boolean

        Get

            Return booIsPlotStyleVpOverridden

        End Get
        Set(ByVal value As Boolean)

            booIsPlotStyleVpOverridden = value

        End Set
    End Property


    Public Property VpNumber() As Integer

        Get

            Return iVpNumber

        End Get
        Set(ByVal value As Integer)

            iVpNumber = value

        End Set
    End Property

    Public Property LayerColor() As Autodesk.AutoCAD.Colors.Color

        Get

            Return colLayerColor

        End Get
        Set(ByVal value As Autodesk.AutoCAD.Colors.Color)

            colLayerColor = value

        End Set
    End Property


    Public Property VpLayerColor() As Autodesk.AutoCAD.Colors.Color

        Get

            Return colVpLayerColor

        End Get
        Set(ByVal value As Autodesk.AutoCAD.Colors.Color)

            colVpLayerColor = value

        End Set
    End Property

End Class

 

Public Class ClassXLLayerMan

'a bunch of variable declarations go here, & then...

Shared liFullLayerDataList As New List(Of FullLayerData)
    Shared fldNewFLD As FullLayerData

    Public Property FullLayerDataList() As List(Of FullLayerData)

        Get

            Return liFullLayerDataList

        End Get

        Set(ByVal value As List(Of FullLayerData))

            liFullLayerDataList = value

        End Set

    End Property

    Private Property NewFLD() As FullLayerData

        Get

            Return fldNewFLD

        End Get

        Set(ByVal value As FullLayerData)

            fldNewFLD = value

        End Set

    End Property
'...a bunch of subs not directly related to the problem go here, & then...

 Private Sub AddFullLayerDataForEachAutocadVP()

        Dim LayLayout As Layout
        Dim strLayoutName As String
        Dim dictLayouts As DBDictionary
        Dim vpVP As Viewport
        'Dim iVpNum As Integer

        Dim iCurrentCvports As Integer = CInt(Application.GetSystemVariable("CVPORT"))
        Dim iCurrentTilemode As Integer = CInt(Application.GetSystemVariable("TILEMODE"))

        Dim MeaninglessId As ObjectId

        ' Dim FLDcount As Integer

        ' FLDcount = 0

        FullLayerDataList.Clear()
        FullLayerDataList.TrimExcess()

        Using Tx As Transaction = ACF.Db.TransactionManager.StartTransaction

            LT = CType(Tx.GetObject(ACF.Db.LayerTableId, OpenMode.ForRead), LayerTable)

            dictLayouts = CType(Tx.GetObject(ACF.Db.LayoutDictionaryId, OpenMode.ForRead), DBDictionary)


            For Each DE1 As DBDictionaryEntry In dictLayouts

                If DE1.Key.ToString() = "Model" Then

                    strLayoutName = "Model"

                    LayoutManager.Current.CurrentLayout = strLayoutName
                    Application.SetSystemVariable("TILEMODE", 1)

                    NewFLD = New FullLayerData

                    FullLayerDataList.Add(NewFLD)

                    NewFLD.IsLayout = False
                    NewFLD.LayoutName = strLayoutName
                    NewFLD.IsModelSpace = False
                    NewFLD.SpaceName = "Model"

                    MeaninglessId = DE1.Value

                    'ReadLayerDataFromAutocad(DE1, False, MeaninglessId, FLDcount)
                    ReadLayerDataFromAutocad(DE1, False, MeaninglessId)

                    NewFLD = Nothing
                    'FLDcount = FLDcount + 1

                Else
                End If



            Next DE1

            For Each DE As DBDictionaryEntry In dictLayouts

                If Not DE.Key.ToString() = "Model" Then

                    LayLayout = CType(Tx.GetObject(CType(DE.Value, ObjectId), OpenMode.ForRead), Layout)

                    strLayoutName = LayLayout.LayoutName

                    LayoutManager.Current.CurrentLayout = strLayoutName

                    For Each id As ObjectId In LayLayout.GetViewports

                        NewFLD = New FullLayerData

                        FullLayerDataList.Add(NewFLD)



                        vpVP = CType(Tx.GetObject(id, OpenMode.ForRead), Viewport)
                        NewFLD.VpNumber = vpVP.Number

                        If NewFLD.VpNumber = 1 Then         'first VP should be PS, strVpNum is nothing until first VP is iterated

                            ACF.Ed.SwitchToPaperSpace()
                            Application.SetSystemVariable("cvport", NewFLD.VpNumber)

                            NewFLD.IsLayout = True
                            NewFLD.LayoutName = strLayoutName
                            NewFLD.IsModelSpace = False
                            NewFLD.SpaceName = "PS"
                            NewFLD.VpNumber = NewFLD.VpNumber

                            'ReadLayerDataFromAutocad(DE, True, id, FLDcount)
                            ReadLayerDataFromAutocad(DE, True, id)

                            NewFLD = Nothing

                            ACF.Ed.SwitchToPaperSpace()

                        Else

                            ACF.Ed.SwitchToModelSpace()
                            Application.SetSystemVariable("cvport", NewFLD.VpNumber)
                            vpVP.UpdateDisplay()

                            NewFLD.IsLayout = True
                            NewFLD.LayoutName = strLayoutName
                            NewFLD.IsModelSpace = True
                            NewFLD.SpaceName = "MS"
                            NewFLD.VpNumber = NewFLD.VpNumber

                            'ReadLayerDataFromAutocad(DE, True, id, FLDcount)
                            ReadLayerDataFromAutocad(DE, True, id)

                            NewFLD = Nothing

                            ACF.Ed.SwitchToPaperSpace()

                        End If

                        'FLDcount = FLDcount + 1

                    Next id
                End If
            Next DE

        End Using

    End Sub

    ' Public Sub ReadLayerDataFromAutocad(ByVal subDE As DBDictionaryEntry, ByRef SubIsLayout As Boolean, ByVal subID As ObjectId, ByRef subFLDcount As Integer)         'SubIsLayout needs to set to false for the model tab, & true for all layout tabs
    Public Sub ReadLayerDataFromAutocad(ByVal subDE As DBDictionaryEntry, ByRef SubIsLayout As Boolean, ByVal subID As ObjectId)
        Dim LTR As LayerTableRecord

        Dim idLineType As ObjectId
        Dim LTTR As LinetypeTableRecord

        Dim LVP As LayerViewportProperties
        Dim vpVP1 As Viewport

        For Each LTRid As ObjectId In LT

            ' Dim supertempFLD = New FullLayerData

            Using Tx1 As Transaction = ACF.Db.TransactionManager.StartTransaction

                LTR = CType(Tx1.GetObject(LTRid, OpenMode.ForRead), LayerTableRecord)

                NewFLD.LayerName = LTR.Name

                NewFLD.ColorName = LTR.Color.ColorNameForDisplay
                NewFLD.LayerColor = LTR.Color

                If SubIsLayout = "true" Then

                    LVP = LTR.GetViewportOverrides(subID)

                    vpVP1 = CType(Tx1.GetObject(subID, OpenMode.ForRead), Viewport)



                    If LVP.IsColorOverridden = True Then

                        NewFLD.IsColorVpOverridden = True
                        NewFLD.VpLayerColorName = LVP.Color.ColorNameForDisplay
                        NewFLD.VpLayerColor = LVP.Color

                        'rRange.Font.Color = Col2Str(LVP.Color)          '/<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

                    Else
                    End If

                    If LVP.IsPlotStyleOverridden = True Then

                        NewFLD.IsPlotStyleVpOverridden = True
                        NewFLD.VpPlotStyleName = LVP.PlotStyleName

                    Else
                    End If

                    If LVP.IsLinetypeOverridden = True Then

                        idLineType = LVP.LinetypeObjectId
                        LTTR = CType(Tx1.GetObject(idLineType, OpenMode.ForRead), LinetypeTableRecord)

                        NewFLD.IsLinetypVpOverridden = True
                        NewFLD.VpLinetypeName = LTTR.Name

                    Else
                    End If

                    If vpVP1.IsLayerFrozenInViewport(LTRid) = True Then  'freeze = yes

                        NewFLD.LayerVpFrozen = True

                    Else
                    End If

                End If

                NewFLD.PlotStyleName = LTR.PlotStyleName

                idLineType = LTR.LinetypeObjectId
                LTTR = CType(Tx1.GetObject(idLineType, OpenMode.ForRead), LinetypeTableRecord)

                NewFLD.LinetypeName = LTTR.Name

                If LTR.IsOff = True Then

                Else

                    NewFLD.LayerON = True

                End If

                If LTR.IsFrozen = True Then  'freeze = yes

                    NewFLD.LayerFrozen = True

                Else     'freeze = no

                End If

                If LTR.IsPlottable = True Then 'noplot = no

                Else

                    NewFLD.LayerNoPlot = True

                End If

            End Using

        Next

    End Sub

 

 

Message 7 of 13
kcimos
in reply to: kcimos

sorry guys, I was trying to edit my code to revert it back to another state & I left a few thing out. Please IGNORE the last block of code in my previous post, which should be this:

 

 Private Sub AddFullLayerDataForEachAutocadVP()

        Dim LayLayout As Layout
        Dim strLayoutName As String
        Dim dictLayouts As DBDictionary
        Dim vpVP As Viewport
        'Dim iVpNum As Integer

        Dim iCurrentCvports As Integer = CInt(Application.GetSystemVariable("CVPORT"))
        Dim iCurrentTilemode As Integer = CInt(Application.GetSystemVariable("TILEMODE"))

        Dim MeaninglessId As ObjectId

        ' Dim FLDcount As Integer

        ' FLDcount = 0

        FullLayerDataList.Clear()
        FullLayerDataList.TrimExcess()

        Using Tx As Transaction = ACF.Db.TransactionManager.StartTransaction

            LT = CType(Tx.GetObject(ACF.Db.LayerTableId, OpenMode.ForRead), LayerTable)

            dictLayouts = CType(Tx.GetObject(ACF.Db.LayoutDictionaryId, OpenMode.ForRead), DBDictionary)


            For Each DE1 As DBDictionaryEntry In dictLayouts

                If DE1.Key.ToString() = "Model" Then

                    strLayoutName = "Model"

                    LayoutManager.Current.CurrentLayout = strLayoutName
                    Application.SetSystemVariable("TILEMODE", 1)

                    NewFLD = New FullLayerData



                    NewFLD.IsLayout = False
                    NewFLD.LayoutName = strLayoutName
                    NewFLD.IsModelSpace = False
                    NewFLD.SpaceName = "Model"

                    MeaninglessId = DE1.Value

                    'ReadLayerDataFromAutocad(DE1, False, MeaninglessId, FLDcount)
                    ReadLayerDataFromAutocad(DE1, False, MeaninglessId)

                    NewFLD = Nothing

                    FullLayerDataList.Add(NewFLD)
                    'FLDcount = FLDcount + 1

                Else
                End If



            Next DE1

            For Each DE As DBDictionaryEntry In dictLayouts

                If Not DE.Key.ToString() = "Model" Then

                    LayLayout = CType(Tx.GetObject(CType(DE.Value, ObjectId), OpenMode.ForRead), Layout)

                    strLayoutName = LayLayout.LayoutName

                    LayoutManager.Current.CurrentLayout = strLayoutName

                    For Each id As ObjectId In LayLayout.GetViewports

                        NewFLD = New FullLayerData

                        vpVP = CType(Tx.GetObject(id, OpenMode.ForRead), Viewport)
                        NewFLD.VpNumber = vpVP.Number

                        If NewFLD.VpNumber = 1 Then         'first VP should be PS, strVpNum is nothing until first VP is iterated

                            ACF.Ed.SwitchToPaperSpace()
                            Application.SetSystemVariable("cvport", NewFLD.VpNumber)

                            NewFLD.IsLayout = True
                            NewFLD.LayoutName = strLayoutName
                            NewFLD.IsModelSpace = False
                            NewFLD.SpaceName = "PS"
                            NewFLD.VpNumber = NewFLD.VpNumber

                            'ReadLayerDataFromAutocad(DE, True, id, FLDcount)
                            ReadLayerDataFromAutocad(DE, True, id)

                            FullLayerDataList.Add(NewFLD)

                            NewFLD = Nothing

                            ACF.Ed.SwitchToPaperSpace()

                        Else

                            ACF.Ed.SwitchToModelSpace()
                            Application.SetSystemVariable("cvport", NewFLD.VpNumber)
                            vpVP.UpdateDisplay()

                            NewFLD.IsLayout = True
                            NewFLD.LayoutName = strLayoutName
                            NewFLD.IsModelSpace = True
                            NewFLD.SpaceName = "MS"
                            NewFLD.VpNumber = NewFLD.VpNumber

                            'ReadLayerDataFromAutocad(DE, True, id, FLDcount)
                            ReadLayerDataFromAutocad(DE, True, id)

                            FullLayerDataList.Add(NewFLD)

                            NewFLD = Nothing

                            ACF.Ed.SwitchToPaperSpace()

                        End If

                        'FLDcount = FLDcount + 1

                    Next id
                End If
            Next DE

        End Using

    End Sub

    ' Public Sub ReadLayerDataFromAutocad(ByVal subDE As DBDictionaryEntry, ByRef SubIsLayout As Boolean, ByVal subID As ObjectId, ByRef subFLDcount As Integer)         'SubIsLayout needs to set to false for the model tab, & true for all layout tabs
    Public Sub ReadLayerDataFromAutocad(ByVal subDE As DBDictionaryEntry, ByRef SubIsLayout As Boolean, ByVal subID As ObjectId)
        Dim LTR As LayerTableRecord

        Dim idLineType As ObjectId
        Dim LTTR As LinetypeTableRecord

        Dim LVP As LayerViewportProperties
        Dim vpVP1 As Viewport

        For Each LTRid As ObjectId In LT

            ' Dim supertempFLD = New FullLayerData

            Using Tx1 As Transaction = ACF.Db.TransactionManager.StartTransaction

                LTR = CType(Tx1.GetObject(LTRid, OpenMode.ForRead), LayerTableRecord)

                NewFLD.LayerName = LTR.Name

                NewFLD.ColorName = LTR.Color.ColorNameForDisplay
                NewFLD.LayerColor = LTR.Color

                If SubIsLayout = "true" Then

                    LVP = LTR.GetViewportOverrides(subID)

                    vpVP1 = CType(Tx1.GetObject(subID, OpenMode.ForRead), Viewport)



                    If LVP.IsColorOverridden = True Then

                        NewFLD.IsColorVpOverridden = True
                        NewFLD.VpLayerColorName = LVP.Color.ColorNameForDisplay
                        NewFLD.VpLayerColor = LVP.Color

                        'rRange.Font.Color = Col2Str(LVP.Color)          '/<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

                    Else
                    End If

                    If LVP.IsPlotStyleOverridden = True Then

                        NewFLD.IsPlotStyleVpOverridden = True
                        NewFLD.VpPlotStyleName = LVP.PlotStyleName

                    Else
                    End If

                    If LVP.IsLinetypeOverridden = True Then

                        idLineType = LVP.LinetypeObjectId
                        LTTR = CType(Tx1.GetObject(idLineType, OpenMode.ForRead), LinetypeTableRecord)

                        NewFLD.IsLinetypVpOverridden = True
                        NewFLD.VpLinetypeName = LTTR.Name

                    Else
                    End If

                    If vpVP1.IsLayerFrozenInViewport(LTRid) = True Then  'freeze = yes

                        NewFLD.LayerVpFrozen = True

                    Else
                    End If

                End If

                NewFLD.PlotStyleName = LTR.PlotStyleName

                idLineType = LTR.LinetypeObjectId
                LTTR = CType(Tx1.GetObject(idLineType, OpenMode.ForRead), LinetypeTableRecord)

                NewFLD.LinetypeName = LTTR.Name

                If LTR.IsOff = True Then

                Else

                    NewFLD.LayerON = True

                End If

                If LTR.IsFrozen = True Then  'freeze = yes

                    NewFLD.LayerFrozen = True

                Else     'freeze = no

                End If

                If LTR.IsPlottable = True Then 'noplot = no

                Else

                    NewFLD.LayerNoPlot = True

                End If

            End Using

        Next

    End Sub

 

Message 8 of 13
_gile
in reply to: kcimos

Hi,

 

Sorry it's quite difficult for me to read VB, and the code you posted does not show all the project structure (Namespaces (?), Modules (?) Imports, ...).

But, from what I can read, the ClassXLLayerMan is absolutely unusefull and does not make the code easily readable.

I'd use local variables in the AddFullLayerDataForEachAutocadVP() method, for the FullDataLayer and List<fullDataLayer> instances and pass each FullDataLayer instance ByRef to the ReadLayerDataFromAutocad() method.

 

        Private Sub AddFullLayerDataForEachAutocadVP()
            '...
            Dim layerDataList As List(Of FullLayerData) = New List(Of FullLayerData)
            '...
            For Each DE1 As DBDictionaryEntry In dictLayouts
                '...
                newFLD = New FullLayerData
                '...
                ReadLayerDataFromAutocad(DE1, newFLD, False, MeaninglessId)
                FullLayerDataList.Add(NewFLD)
                '...
            Next DE1
            '...
        End Sub

        Public Sub ReadLayerDataFromAutocad(ByVal subDE As DBDictionaryEntry, ByRef fld As FullLayerData, _
                                            ByRef SubIsLayout As Boolean, ByVal subID As ObjectId)
            '...
        End Sub

 

 

In the ReadLayerDataFromAutocad(), you change the properties of NewFLD for each LayerTableRecord in the LayerTable (and start a new Transaction which is unusefull as this method from within the transaction opened in the calling method).

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 9 of 13
ssomick
in reply to: _gile

using a STRUCTURE did the trick. I really don't understand why, but I will hopefully someday ( I am a newbie after all).

 

thanks for the helps.

Message 10 of 13
_gile
in reply to: ssomick

Hi,

 

Have a look here and/or google for "Value type vs Reference type".

 

You can also run this little console application which is quite self explanatory:

 

    class RefType
    {
        public string Name;

        public RefType(string name)
        {
            Name = name;
        }
    }

    struct ValType
    {
        public string Name;

        public ValType(string name)
        {
            Name = name;
        }
    }

    class Program
    {
        static void Main()
        {
            ValType val1 = new ValType("val1");
            ValType val2 = val1;

            RefType ref1 = new RefType("ref1");
            RefType ref2 = ref1;

            val2.Name = "val2";
            ref2.Name = "ref2";

            Console.WriteLine(val1.Name); // prints: "val1"
            Console.WriteLine(val2.Name); // prints: "val2"

            Console.WriteLine(ref1.Name); // prints: "ref2"
            Console.WriteLine(ref2.Name); // prints: "ref2"
        }
    }

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 11 of 13
jeff
in reply to: _gile

Your problem is your adding a shared (static) field of a class however many times.

 

So a shared or static variable for a reference type like in your code points to the same memory location(it actually might get moved around some for optimization), but that variable will always point to same object., and you are just changing the properties of the same object.

 

A variable is just a way in your source code for a name to point to a memory slot.

 

 

A couple of points

 

Reference types by default are passed by value contrary to what you read in books, etc...

 

A value type point to the memory slots that actually that contain the data..

 

A variable for a reference type points to a memory slot that holds only 2 things.

1. Null

2. The address in memory where the object data is stored.

 

 

Dim a as New Class

That just creates a Class object then the varaible 'a' points to a memory slot which contains the address to the object.

Dim b as Class = a

Now b is a different memory slot but is assigned the value of 'a' which is the address of same object.

a.Property = 3

b.Property = 4

All that is happening is when you assign the property using a or b is they are told to modify the property of the object located at the same address.

 

Anything you change with a or b they are going to the same place to update the data.

That is one reason people say reference types are passed by ref.

 

You can assign a = null but b still holds the address to the object.

or

Dim c as new Class

b = c

now b and c hold the address that points to the same object and 'a' value is the address of first object created

 

Now if you pass a reference type by byref you are associating the argument with the same memory slot.

So they both will modify the same object but they both go to the smae memory slot to get that address.

So setting one to null  then both will be null

 

Strings are just a an array of chars and are actully a reference type but are imuttable so they act like a value type.

 

I got a boss on top of me wanting to get a project out and typed this very quickly so probaly not very clear but I was actully planning on doing a post about this topic that will explain it much better with code and pics and go over so other fundamentals that would help expalin it, but boss man is about to come back in check on progress so will give a much better explanation in the next couple of days

 

 

You can also find your answers @ TheSwamp
Message 12 of 13
jeff
in reply to: jeff

The first part was incorrect your not changing the object your changing address it holds which points to a different object.

 

So a shared or static variable for a reference type like in your code points to the same memory location(it actually might get moved around some for optimization), but that variable will always points to the same memory location., and you are just changing the addresss it points to.

 

 

 

You can also find your answers @ TheSwamp
Message 13 of 13
khoa.ho
in reply to: jeff

>>I got a boss on top of me wanting to get a project out and typed this very quickly so probaly not very clear but I was actully planning on doing a post about this topic that will explain it much better with code and pics and go over so other fundamentals that would help expalin it, but boss man is about to come back in check on progress so will give a much better explanation in the next couple of days<<

 

Probably we would NOT let the boss man and colleagues to know that we are playing around with this forum during working hours. 🙂

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost