Zum Inhalt springen

Lsteinme

Mitglieder
  • Gesamte Inhalte

    65
  • Benutzer seit

  • Letzter Besuch

Beiträge von Lsteinme

  1. ok,

    Dim myExportSheet As Worksheet = CType(excelApp.Workbooks.Open(importfile).Sheets.Item(1), Worksheet)

    war der code der mir das Worksheetliefert von dem ich auslesen will, ob das jetzt geklappt hat weiß ich noch net 3 von 4 Threads blieben ganz Blank im result, was nicht sein sollte, aber logische Gründe haben könnte.

    Von miraus hier mal der relevante Code für die Threadbearbeitung:

    Aufrufende Klasse die jede menge tut was eigentlich mit dem problem nix zu tun hat:

    
    sub FUNKTIONSNAME()
    
    Dim myExportSheet As Worksheet = CType(excelApp.Workbooks.Open(importfile).Sheets.Item(1), Worksheet)
    
    ...
    
    With treadcontrol
    
                            Dim wieviele As Integer = myExportSheet.UsedRange.Rows.Count
    
                            Dim rest As Integer = wieviele Mod .anzCores
    
                            Dim startvalues(.anzCores - 1) As Integer
    
                            Dim endvalues(.anzCores - 1) As Integer
    
    
                            Dim currententry As Integer = 0
    
    
                            For i As Integer = 0 To startvalues.Count - 1
    
                                startvalues(i) = currententry + 1
    
                                endvalues(i) = CInt(Fix(wieviele / .anzCores)) + currententry
    
                                currententry = endvalues(i)
    
                                If ((i + 1).Equals(.anzCores)) Then
    
                                    endvalues(i) = endvalues(i) + (wieviele Mod (.anzCores))
    
                                End If
    
                                treadcontrol.createNewSearchingThread(startvalues(i), endvalues(i), myExportSheet, i)
    
                            Next
    
                        End With
    
    End Sub
    
    'wenn hier alles gescheit ankommt is der rest egal
    
    Public Function resumeRM_Import(e As List(Of UncastedProjektmitarbeiter)) As Boolean Handles 
    
    ...
    
     End Function
    
    
    Klasse ThreadControl:
    Public Class Threadcontrol
    
        Public Event excelloadfinished(list As List(Of UncastedProjektmitarbeiter))
    
        'this is a current version, if the Working PCs get more cores, increase this number
    
        Public anzCores As Integer = 4
    
        Private _oPX_Logic As OPX_Logic
    
        Private finished(anzCores - 1) As Boolean
    
        Dim ExcelLoadObject(anzCores - 1) As ExcelLoadThread
    
     Sub New(oPX_Logic As OPX_Logic)
    
            ' TODO: Complete member initialization 
    
            _oPX_Logic = oPX_Logic
    
        End Sub
    
    
    
        Sub createNewSearchingThread(startvalues As Integer, endvalues As Integer, myExportSheet As Worksheet, i As Integer)
    
            ExcelLoadObject(i) = New ExcelLoadThread(startvalues, Me, myExportSheet, i, endvalues)
    
            Dim excelloadThread As New Threading.Thread(AddressOf ExcelLoadObject(i).startreading)
    
            excelloadThread.Start()
    
        End Sub
    
    
        Public Sub threadfinishedHandler(e As Integer)
    
            finished(e) = True
    
            Dim all As Boolean = True
    
            For Each index As Boolean In finished
    
                If (index = False) Then
    
                    all = False
    
                    Exit For
    
                End If
    
            Next
    
            If (all) Then
    
                Dim newList As New List(Of UncastedProjektmitarbeiter)
    
                For index As Integer = 0 To anzCores - 1
    
                    newList.AddRange(ExcelLoadObject(index).mitarbeiters)
    
                Next
    
                RaiseEvent excelloadfinished(newList)
    
            End If
    
        End Sub
    
    
    End Class
    
    
    ThreadKlasse:
    
    Imports Microsoft.Office.Interop
    
    Imports System.Globalization
    
    
    Public Class ExcelLoadThread
    
        Public Event threadfinished(e As Integer)
    
        Public mitarbeiters As New List(Of UncastedProjektmitarbeiter)
    
        Dim mysheet As Worksheet
    
        Dim startrow As Integer
    
        Dim endrow As Integer
    
        Dim index As Integer
    
        Sub New(startrow As Integer, control As Threadcontrol, sheet As Excel.Worksheet, index As Integer, Optional endrow As Integer = 0)
    
            Me.startrow = startrow
    
            Me.endrow = endrow
    
            Me.index = index
    
            mysheet = sheet
    
            AddHandler threadfinished, AddressOf control.threadfinishedHandler
    
        End Sub
    
    
        Sub startreading()
    
            For Each r As Excel.Range In mysheet.Range(mysheet.Cells(startrow, 1), mysheet.Cells(endrow, 16))
    
                Dim Rescol As String = CStr(CType(r.Cells(1, 3), Excel.Range).Value)
    
                If (String.IsNullOrEmpty(Rescol) OrElse Rescol.Equals("")) Then
    
                    Exit For
    
                End If
    
    
                If (Rescol.Contains("Ressource") Or Rescol.Contains("Gen.Res.")) Then
    
                    Continue For
    
                End If
    
                Dim BEcol As String = CStr(CType(r.Cells(1, 5), Excel.Range).Value)
    
                If String.IsNullOrEmpty(BEcol) OrElse Not BEcol.Contains("BE") Then
    
                    Continue For
    
                End If
    
                Dim datum As Date
    
                Date.TryParseExact(CStr(CType(CType(r, Excel.Range).Cells(1, 16), Excel.Range).Value), "dd.MM.yyyy", New CultureInfo("de-DE"), Globalization.DateTimeStyles.None, datum)
    
                Dim rollnumber As String = CStr(CType(CType(r, Excel.Range).Cells(1, 6), Excel.Range).Value)
    
                mitarbeiters.Add(New UncastedProjektmitarbeiter(Rescol, BEcol, rollnumber, datum))
    
            Next
    
            RaiseEvent threadfinished(index)
    
        End Sub
    
    
    End Class
    
    

    Hoffe das war nun erhellend ich halts er für verwirrend, weswegen ich den Code nicht gleich gepostet hab^^

    Kurz zur Erklärung: das Programm liest eine speziellformatierte Exceldatei ein, parsed die Daten, und speichert sie in der DB (falls sich was geändert hat) im code steht jetzt nur das Excelauslesen

    Gruß Lucas

  2. Hi Leute, ich hab mal wieder ein Problem^^

    Und zwar wollt ich im Geschäft eine relativ umfangreiche Exceltabelle auslesen (über 10k Zeilen)

    Da das sehr lange dauert, im naitiv Ansatz (ein Thread der alle verwendeten Rows durchläuft) hab ich mir gedacht, versuchs doch mal Multithreaded.

    Ich hab aktuell ne 3 Klassen Struktur aufgebaut:

    eine Klasse die die Auslesung anfordert, die tut aber noch mehr, das funktioniert aber schon^^

    eine Klasse namens ThreadControl die ich eigentlich nur als Zwischenklasse eingezogen hab, vielleicht braucht man sowas ja nochmal

    und eine Klasse die den Thread darstellt.

    Jetzt is aber das Problem: ich bekomm eine HResult Message (0x800A03EC) raus wenn das ganze anfängt zu laufen. Jetzt meine Frage, liegts ehr an meinem Code, oder erlaubt Excel kein auslesen mehrer Threads zugleich?

    Gruß Lucas

  3. Es handelt sich um eine selbst erstellte Komponente?

    Du kannst Variablen mit Standardwerten initialisieren. Wenn Du dann die korrekten Daten setzt, werden diese dann überschrieben.

    Musst Dich dann halt daran kümmern, dass das Control / die Komponente dann neu gezeichnet wird.

    Jau is eine selbst erstellte.

    Verpass ich da grade irgendwas? wenn sich nur das Tablelayout später verändert, muss ich dann nicht nur für dieses layout ein Refresh aufrufen? oder muss ich das für das volle Window machen? weil wenn ich meinen Code nun entsprechend abändere:

    Public Class Projekt_PPQA_Management
    
        'true if process is NA else false saves "old" states
    
        Public states As New Dictionary(Of Integer, Boolean)
    
    
        Public boxes As New Dictionary(Of Integer, System.Windows.Forms.CheckBox)
    
        Dim realini As Boolean = False
    
        'this is only a Methode for the designer, IT DOES NOT DISPLAY THE CORRECT FULL LAYOUT!
    
        Sub New()
    
            InitializeComponent()
    
            MainPane.RowCount = 2
    
            MainPane.CellBorderStyle = TableLayoutPanelCellBorderStyle.Inset
    
            While (MainPane.RowStyles.Count <= MainPane.RowCount - 1)
    
                MainPane.RowStyles.Add(New RowStyle(SizeType.AutoSize))
    
            End While
    
            MainPane.RowStyles.Add(New RowStyle(SizeType.Percent, 50.0!))
    
            MainPane.ColumnCount = 2
    
            MainPane.ColumnStyles(0).SizeType = SizeType.AutoSize
    
            MainPane.RowStyles(0).SizeType = SizeType.AutoSize
    
            MainPane.RowStyles(1).SizeType = SizeType.AutoSize
    
            Dim ProcessHeaderLabel As New System.Windows.Forms.Label
    
            ProcessHeaderLabel.Text = "Processnames"
    
            ProcessHeaderLabel.Font = New System.Drawing.Font(ProcessHeaderLabel.Font, FontStyle.Bold)
    
            ProcessHeaderLabel.Dock = DockStyle.Fill
    
            ProcessHeaderLabel.TextAlign = ContentAlignment.MiddleCenter
    
            Dim NALabel As New System.Windows.Forms.Label
    
            NALabel.Text = "Enabled for this Project"
    
            NALabel.Font = New System.Drawing.Font(ProcessHeaderLabel.Font, FontStyle.Bold)
    
            NALabel.AutoSize = True
    
            NALabel.Dock = DockStyle.Fill
    
            NALabel.TextAlign = ContentAlignment.MiddleLeft
    
            'the two headers
    
            MainPane.Controls.Add(ProcessHeaderLabel)
    
            MainPane.Controls.Add(NALabel)
    
        End Sub
    
    
        'This special init Methode is needed, so the Designerview (bevor runtime) won't crash
    
        Public Sub myGUIinit(proj As Projekt)
    
            If Not realini Then
    
                ' This call is required by the designer.
    
                InitializeComponent()
    
    
                ' Add any initialization after the InitializeComponent() call.
    
                realini = True
    
                MainPane.RowCount = Process_Dict.Keys.Count + 2
    
                MainPane.CellBorderStyle = TableLayoutPanelCellBorderStyle.Inset
    
                While (MainPane.RowStyles.Count <= MainPane.RowCount - 1)
    
                    MainPane.RowStyles.Add(New RowStyle(SizeType.AutoSize))
    
                End While
    
                MainPane.RowStyles.Add(New RowStyle(SizeType.Percent, 50.0!))
    
                MainPane.ColumnCount = 2
    
                MainPane.ColumnStyles(0).SizeType = SizeType.AutoSize
    
                MainPane.RowStyles(0).SizeType = SizeType.AutoSize
    
                MainPane.RowStyles(1).SizeType = SizeType.AutoSize
    
                Dim ProcessHeaderLabel As New System.Windows.Forms.Label
    
                ProcessHeaderLabel.Text = "Processnames"
    
                ProcessHeaderLabel.Font = New System.Drawing.Font(ProcessHeaderLabel.Font, FontStyle.Bold)
    
                ProcessHeaderLabel.Dock = DockStyle.Fill
    
                ProcessHeaderLabel.TextAlign = ContentAlignment.MiddleCenter
    
                Dim NALabel As New System.Windows.Forms.Label
    
                NALabel.Text = "Enabled for this Project"
    
                NALabel.Font = New System.Drawing.Font(ProcessHeaderLabel.Font, FontStyle.Bold)
    
                NALabel.AutoSize = True
    
                NALabel.Dock = DockStyle.Fill
    
                NALabel.TextAlign = ContentAlignment.MiddleLeft
    
                'the two headers
    
                MainPane.Controls.Add(ProcessHeaderLabel)
    
                MainPane.Controls.Add(NALabel)
    
    
                For Each p As Integer In Process_Dict.Keys
    
                    Dim namelabel As New System.Windows.Forms.Label
    
                    namelabel.AutoSize = True
    
                    namelabel.Text = Process_Dict(p)
    
                    namelabel.Dock = DockStyle.Fill
    
                    namelabel.TextAlign = ContentAlignment.MiddleLeft
    
    
                    Dim NACheckbox As New System.Windows.Forms.CheckBox
    
                    boxes(p) = NACheckbox
    
                    If (proj.NA_Processes.Contains(p)) Then
    
                        NACheckbox.Checked = True
    
                        states(p) = True
    
                    Else
    
                        NACheckbox.Checked = False
    
                        states(p) = False
    
                    End If
    
                    NACheckbox.CheckAlign = ContentAlignment.MiddleCenter
    
                    MainPane.Controls.Add(namelabel)
    
                    MainPane.Controls.Add(NACheckbox)
    
                Next
    
            End If
    
            MainPane.Refresh()
    
        End Sub
    
    End Class
    
    

    und beim Tapwechsel der GUI welche meine Form enthält die myGUIinit Methode aufrufe, tut sich garnix, die beiden Labels die ich standartmäßig einbauen kann bleiben erhalten, aber von einer neuzeichnung ist nichts zu sehen

  4. Hi leuts,

    Problem wie folgt:

    Ich hab eine GUI-Componete die eigentlich erst zur laufzeit korrekt erstellt werden kann,

    liegt daran das sie für einige Dimensionierungen des Tabellayouts was darin abläuft einen mit DB-Daten gefüttertes Dictionary braucht.

    Nun die Frage: kann ich dem Designer irgendwie fixe Standardwerte geben die er für das Anzeigen auswerten kann?

    Es handelt sich leider um ein größeres Fenster, welches neben meiner Componete noch andere enthält und evt auch noch erweitert werden soll, daher is es unschön wenn der Designer nichtmehr tut^^

    Die Fehlermeldung wegklicken führt ja zu leider dazu das die Componete einfach vom Layout entfernt wird.

    Hier mal der Code der Componete, den ich von hand schreiben muss, den Designercode erspar ich euch mal^^

    Public Class Projekt_PPQA_Management
    
        'true if process is NA else false saves "old" states
    
        Public states As New Dictionary(Of Integer, Boolean)
    
    
        Public boxes As New Dictionary(Of Integer, System.Windows.Forms.CheckBox)
    
        Sub New([B][U]proj As Projekt[/U][/B])
    
            ' This call is required by the designer.
    
            InitializeComponent()
    
            MainPane.CellBorderStyle = TableLayoutPanelCellBorderStyle.Inset
    
            ' Add any initialization after the InitializeComponent() call.
    
            MainPane.RowCount = Process_Dict.Keys.Count + 2
    
    
            While (MainPane.RowStyles.Count <= MainPane.RowCount - 1)
    
                MainPane.RowStyles.Add(New RowStyle(SizeType.AutoSize))
    
            End While
    
            MainPane.RowStyles.Add(New RowStyle(SizeType.Percent, 50.0!))
    
            MainPane.ColumnCount = 2
    
            MainPane.ColumnStyles(0).SizeType = SizeType.AutoSize
    
            MainPane.RowStyles(0).SizeType = SizeType.AutoSize
    
            MainPane.RowStyles(1).SizeType = SizeType.AutoSize
    
            Dim ProcessHeaderLabel As New System.Windows.Forms.Label
    
            ProcessHeaderLabel.Text = "Processnames"
    
            ProcessHeaderLabel.Font = New System.Drawing.Font(ProcessHeaderLabel.Font, FontStyle.Bold)
    
            ProcessHeaderLabel.Dock = DockStyle.Fill
    
            ProcessHeaderLabel.TextAlign = ContentAlignment.MiddleCenter
    
            Dim NALabel As New System.Windows.Forms.Label
    
            NALabel.Text = "Enabled for this Project"
    
            NALabel.Font = New System.Drawing.Font(ProcessHeaderLabel.Font, FontStyle.Bold)
    
            NALabel.AutoSize = True
    
            NALabel.Dock = DockStyle.Fill
    
            NALabel.TextAlign = ContentAlignment.MiddleLeft
    
            'the two headers
    
            MainPane.Controls.Add(ProcessHeaderLabel)
    
            MainPane.Controls.Add(NALabel)
    
    
            For Each p As Integer In Process_Dict.Keys
    
                Dim namelabel As New System.Windows.Forms.Label
    
                namelabel.AutoSize = True
    
                namelabel.Text = Process_Dict(p)
    
                namelabel.Dock = DockStyle.Fill
    
                namelabel.TextAlign = ContentAlignment.MiddleLeft
    
    
                Dim NACheckbox As New System.Windows.Forms.CheckBox
    
                boxes(p) = NACheckbox
    
                If (proj.NA_Processes.Contains(p)) Then
    
                    NACheckbox.Checked = True
    
                    states(p) = True
    
                Else
    
                    NACheckbox.Checked = False
    
                    states(p) = False
    
                End If
    
                NACheckbox.CheckAlign = ContentAlignment.MiddleCenter
    
                MainPane.Controls.Add(namelabel)
    
                MainPane.Controls.Add(NACheckbox)
    
            Next
    
        End Sub
    
    End Class
    
    

    Gruß Lucas

  5. ok Kommando zurück geht doch nicht, hatte vergessen einige auskomentierte staments wieder rein zu nehmen die aber für die Perfomance wichtig sind.

    Eine intresse Beobachtung ist aber, wahr ein Clone einmal datasource für den DGV wird er nicht mehr gelöscht, entferne ich die entsprechende beiden Zeilen (zuweisung des Clones als DataSource und zuweisung des Orginals (was nun aktuallisiert ist) als Datasource) aus dem auszführenden Code, wird der Platz den der Clone braucht irgendwann wiederverwertet. sind die beiden Zeilen aber drin, wird der Platz vom Clone nie wiederverwertet, kann es sein das die Datasource Methode vom DGV irgendwelche Logs aufbaut in denen all ihre Datasources gespeichert werden?

  6. Achso, ok dann hab ich den GC wohl etwas falsch verstanden, ebenso wie den Artikel den lbm gepostet hat, dort stand ja auch "discards the elemtents" was für mich wegwerfen heißt^^ dann bleibt aber immernoch die frage warum der Arbeitsspeicher dann immer weiter anwächst, eigentlich sollten dann ja da (laut Artikel von lbm) lücken entstehen, wie gesagt die objekte sind zwischen 2,5 und 5 MB groß, nur werden diese Lücken augenscheinlich nie wieder gefüllt sondern es wird nur oben drauf gepackt, indiz: der Speicherverbrauch nimmt nie ab^^

    Andere Seitenfrage: Kann man den den LOH eigentlich irgendwie dazu zwingen bestehende Lücken zu schließen?

    EDIT:

    Ok Problem gelöst, dispose hilft doch, muss es nur an der richtigen stelle anstetzen, nämlich am clone selbst nicht am DGV^^ Ich hab immer gedacht die dispose methode gäbe es nur bei Grafischen Componenten wie Label DGV und co, danke Silent

  7. Auf dem Clone passiert nix, das is der Trick bei der Sache, der Clone is nur eine temporäre kopie, damit mein DGV sich nicht während dem 2maligen säubern und befüllen der Datatable dauernt neu zeichnen will, das hat sehr (optisch) hässliche nebenwirkungen. Alles weitere läuft über die Orginaltabelle ab, deswegen wird die auch am ende wieder als Datasource gesetzt. Zum GC: ich hab mir den Artikel durchgelesen, sowie damals in meinem Unterricht zum Thema GC aufgepasst, dort steht auch: (grob übersetzt) das der GC alle jene Objekte einsammelt, die nicht mehr von einem aktiven primärelement der Anwendung verwende werden. Wenn ich also explizit den GC.collect aufrufe sollte der Collector doch eigentlich den Clone, so wie dessen Reihen und Cellen einsammeln, da diese keinerlei Referenzen auf die Hauptanwendung mehr haben dürften oder lieg ich da falsch und vergesse irgend eine spezielle referenz der geclonten Datatable zur Anwendung?

    Dispose kann ich hier nicht verwenden, weil die person die diesen DGV programmiert hat, sämmtliche Logik in selbigem belassen hat, heißt wenn ich den dispose, läuft garnix mehr^^ + Das dem Nutzer warscheinlich ein plötzlich leerer Raum auf dem Bildschrim auffallen würde, auch wenn dieser kurz darauf wieder besetzt ist.

  8. Hallo Leute,

    ich hab mal wieder ein Problem, und weis nicht woran es liegt bzw wie ich es löschen soll

    Folgendes:

    Ich clone zu beginn eines Methodenaufrufs eine Datatable (weil ich sie als Source für nen DGV brauche). das dumm ist nur wenn ich den Clone später nicht mehr brauche, wird er nicht beseitigt, sonst bleibt im speicher (richtig schön im Arbeitsspeicher zu sehen, der wächst immer um circa 5MB an was schon ordentlich is (ka warum der clone so viel speicher braucht) das komische ist halt, nach dem ich den clone nicht mehr brauche, rufe ich sogar explict GC.collect auf, es tut sich aber nix, der Speicherverbaucht wächst weiter an.

    wer weiß rat?

    hier kurz ein Ausschnitt aus dem Code:

      dtclone = dtProjects.Clone
    
            Dim Rows As IEnumerable(Of Projekt) = Projekt_Dictionary.Values
    
            Me.DataSource = dtclone
    
            dtProjects.Clear()
    
            If (Not IsNothing(stateTypesColsSorted) AndAlso Not IsNothing(roleIdsColsSorted.Any)) Then
    
                For Each proj As Projekt In Rows
    
                    dtProjects.Rows.Add(GetValuesForRows(proj))
    
                Next
    
            End If
    
    
            Rows = FilterForText(dtProjects, Rows)
    
            Rows = FilterForActivProjects(Rows)
    
            Rows = FilterForEstimation(Rows)
    
            Rows = FilterForMyProjectsAndSubs(Rows)
    
            dtProjects.Clear()
    
            If (Not IsNothing(stateTypesColsSorted) AndAlso Not IsNothing(roleIdsColsSorted.Any)) Then
    
                For Each proj As Projekt In Rows
    
                    dtProjects.Rows.Add(GetValuesForRows(proj))
    
                Next
    
            End If
    
            Me.DataSource = dvProjects
    
     dtclone.Clear()
    
            dtclone = Nothing
    
            GC.Collect()
    
    

    Ohne das cloning wird mein DGV sehr träge, ich kann ihn aber auch nicht einfach über .suspendLayout ruhigstellen weil leider alles in diesem DGV abläuft (ist eine Abgeleitete Classe von einem MS-DGV), tu ich es doch, tuen meine filter nichtmehr was sie sollen.

    Die beiden For-Schleifen brauch ich, da beim eintritt, die datatable veraltet ist (es steht nur das drin was letztes mal nicht rausgeflogen ist). Leider braucht einer meiner Filter (der Textfilter) auch den DGV, weil er sich hier daten aus Sichtbarencolumns ziehen muss das könnte ich zwar auch (mit paar trichs) über die Datatable regeln, was ich auch versucht hab, aber die perfomance is dennoch nicht sehr gut weil der DGV zu oft zeichnet wenn er direkt die ganze zeit die richtige Datatable als Source hat.

    Kurz um: kann mir bitte jemand sagen warum in diesem Fall mein Arbeitsspeicher immer weiter anwächst, wenn ich ein objekt clone, später aber alle referenzen auf den Clone beseitige? hab ich vielleicht irgendwelche refernzen vergessen zu bedenken? ich weiß grad echt nicht weiter

    Gruß

    Lucas

  9. Hast recht, hab zwischenZeitlich auch entdeckt das ich neben der Datatable, die dem DGV zu grunde liegt noch dictionarys habe aus denen sich ja das ganze speist, also geh ich mit LINQ einfach über die drüber. Wobei ich jetzt, zum austesten des ganzen, auf ein hässliches Problem gestoßen bin, was sich aber hoff ich durch bisschen Nachdenken lösen lässt. Die Kurzfassung: es gibt sichtbare und unsichtbare Columns im DGV, deren Sichtbarkeit ist aber nicht statisch sondern der Nutzer kann sich aussuchen welche columns er grad sehn will, was beim (ebenfallsintegrierten) Textfilter evt hässlich wird^^

    Aber denk das sollt ich hin bekommen, danke für den Support

    Gruß Lucas

  10. Würde auch mit LINQ funktionieren :-)

    Wie is denn in VB.net die Notation mit der ich eine LINQ Anfrage auf eine Datatable loslassen kann? wenn ichs einfach so versuche, bekomm ich nen fehler der aussagt, ne Datatable sei nicht für LINQ Statements geeignet

  11. Das klingt doch schonmal viel besser wie meine Notidee^^, aber wenn die die gruppiere, kann ich dann dennoch beide Ordnen? in der Tabelle stehen ja sowohl Projekte als auch Teilziele und BEIDE sollen geordnet sein, dabei aber nicht "zerrissen" werden, also das nachher ein Projekt ganz wo anders in der alphabetischen Ordnung steht als ein Teilziel. Auf jeden Fall werd ich mich mal in dieses Linq einlesen, das scheint ja recht praktisch zu sein.

    Herzlichen Dank

  12. Ok, hab ne Lösung gefunden, auch wenn sie wahrscheinlich unnötig Kompliziert ist und einen anderen Nachteil nachsich zieht:

    Ich hab einfach eine neue Spalte in meine DT eingezogen, die einen String mit dem Projektnamen+(falls vorhanden)Teilzielnamen beinhaltet. wenn der Nutzer nun auf die normale Namen spalte klickt, wird nach dieser eignetlich Unsichbaren Spalte sortiert.

    Nachteil: dreht man die Sortorder rum, steht das Projekt unter den Teilzielen xD, aber naja, da ich sowieso die automatische Sotierung der Spalten ausschalten musste, hab ich halt einfach die invertierung des Sortbefehls für den Namen nicht eingebaut, mag nicht sehr schön sein, funtkioniert aber.

    Falls wem was besseres einfällt, ich bin da für alles Offen^^

  13. Hallo Leute,

    Ich hab ein kleines Problem mit dem Anzeigen meiner Daten im Dataview welcher meinem Datagridview zugrunde liegt.

    Und zwar, muss ich für eine Spalte in meiner Dataview, der sich aus einer Datatable speist, eine besondere Sortierprozedur erstellen, da hier mehre Objekttypen zusammenspielen. Wenn die Daten im DGV direkt liegen ist das ja kein Problem, da nimmt man einfach das Hauseigene SortCompare oder Sorted Event und bastelt daran rum.

    Wie kann ich aber das ganze dahingehend verändern, das ich auch in einem Dataview eine etwas angepasste Sortierfunktion einbauen kann? Im Internet hab ich zwar immer wieder die schönen Links zur MicrosoftLib gefunden, aber da steht au nur wie man in einem DataView (naiv) nach einer oder mehreren Spalten sortiert und ne Sortorder mit gibt, was für meinen fall halt leider net ausreicht, siehe Szenario

    Das Szenario is wie folgt:

    in meinem DGV werden Projekte und Teilziele dieser Projekte angezeigt.

    wir nun nach dem Namen sortiert sollen zwar die Projekte neu sortiert werden, die Teilziele, die per Default direkt unter den Projekten stehen, aber sollen mit den Projekten mit wandern und somit immer bei ihrem Projekt bleiben.

    Mein bisher in der Theorie erfolgsversprechendster Versuch sah dabei wie folgt aus:

    ich habe für den Namen aller Einträge in der Datatable eine neue Klasse erstellt. (MyString)

    Diese hat die Compare und CompareTO methoden implementiert so wie die ToString methode überschrieben.

    Beim erstellen eines neuen MyStrings wurde dann Typ des Eintrags mitgegeben und dem entsprechend 2 Einträge gesetzt, der "shownname" sowie der "identname". Im Falle eines Teilziels wird der identname durch eine Kombination von "Projektname" und "Teilzielname" gebildt.

    In den Compare Methoden hab ich dann einfach die StringCompare() Methode angewandt um jeweils die identnamen miteinander zu vergleichen.

    Was in der Theorie ganz gut klang, scheint den Dataview beim sortieren aber nicht weiter zu interessieren, augenscheinlich sortiert er weiterhin nur nach dem angezeigten Namen und verwendt nicht die Compare Methoden meiner MyString Klasse.

    Gruß lsteinme

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...