Archiv des Tags “VB.net”

ComboBox mit AutoResizeDropDownWidth()

1. November 2010, 18:27 Uhr

In einem VB.net-Projekt verwenden ich Kombinationsfelder (ComboBox) zum Auswählen von Werten. Allerdings sind die Werte zum Teil sehr lang und wurden in der Liste nicht mehr komplett angezeigt.

Zwar stellt eine ComboBox die Eigenschaft DropDownWidth zur Verfügung, worüber man die Breite der Liste einstellen kann, aber es gibt leider keine Funktion zum Ermitteln der benötigten Breite.

Im Netz habe ich ein paar Beispiele gefunden, wie man den breitesten Eintrag ermitteln kann, und mir daraus folgenden Code gebaut:

Public Class MyComboBox
    Inherits System.Windows.Forms.ComboBox

    ''' <summary>
    ''' ...
    ''' </summary>
    Public Sub AutoResizeDropDownWidth()
        Dim iWidestWidth As Integer = 0

        Using g As Graphics = Me.CreateGraphics
            For Each oItem As Object In Me.Items 'Für alle Einträge...
                Dim sItemText = Me.GetItemText(oItem)
                Dim oItemSize As SizeF = g.MeasureString(sItemText, Me.Font)

                iWidestWidth = Math.Max(iWidestWidth, oItemSize.Width)
            Next oItem
        End Using

        If Me.Items.Count > Me.MaxDropDownItems Then 'Wenn die Scrollleiste angezeigt wird...
            iWidestWidth += 15
        End If

        Me.DropDownWidth = Math.Max(iWidestWidth, Me.Width)
    End Sub

End Class

Ich leite mir eine MyComboBox von der Original ComboBox ab und füge ihr die Methode AutoResizeDropDownWidth() hinzu. Wenn man diese Methode aufruft, wird die Liste so breit gemacht, dass der breiteste Eintrag (+Scrollleiste) passt, sie aber nicht kleiner wird, als die ComboBox selber.

Der Quelltext funktioniert sowohl wenn man die Einträge über Add() hinzufügt, als auch wenn man mit einer DataSource arbeitet.

My.Settings.Upgrade()

27. September 2010, 18:34 Uhr

Ich habe in der letzten Woche das erste Mal mit My.Settings bei einem VB.net-Projekt gearbeitet und finde es eigentlich recht praktisch: Man kann Einstellungen laden und speichern ohne sich selbst um die Datenhaltung zu kümmern.

Jetzt habe ich aber festgestellt, dass die Daten versionsabhängig gespeichert werden. Dass heißt, wenn sich die Versionsnummer eines Projektes ändert, werden die Einstellungen mit den Standardwerten angelegt und die alten Werte nicht automatisch übernommen.

Man kann mit dem Befehl My.Settings.Upgrade() zwar Einstellungen aus vorherigen Versionen übernehmen, muss aber beachte, die aktuellen Einstellungen überschrieben werden. Einfach stur die Upgrade()-Methode beim Programmstart ausführen ist da leider falsch.

Das einfachste ist, wenn man eine Einstellung Upgraded (als Boolean) hinzufügt und standardmäßig auf False setzt. Beim Starten der Anwendung überprüft man ob diese Einstellung auf True gesetzt ist. Wenn nicht, führt man die Methode My.Settings.Upgrade() aus und setzt My.Settings.Upgraded auf True.

So werden die Einstellungen nur beim ersten Start aktualisiert:

If Not My.Settings.Upgraded Then 'Wenn My.Settings noch nicht aktualisiert wurde...
    My.Settings.Upgrade()
    My.Settings.Upgraded = True
End If

P.S.: Die Benutzer-Einstellungen werden übrigens als XML-Dateien in Unterordner im Pfad %LOCALAPPDATA% (z. B. C:UsersBenutzernameAppDataLocal bei Windows 7) gespeichert.

ObjectARX: DocumentLock bei modalen Fenstern verwenden

19. Juni 2009, 18:29 Uhr

Wir portieren auf der Arbeit gerade ein altes AutoCAD VBA-Projekt mit Hilfe von ObjectARX nach VB.net.

ObjectARX ist supermächtig, aber für Neueinsteiger gibt es einige Klippen zu umschiffen. Ich möchte behaupten, dass wir die meisten schon gerammt haben, aber immer noch auf Fahrt sind! ;)

Eine gute Quelle ist übrigens der Blog von Kean Walmsley!

Beim letzten Problem hatte ich eine Funktion geschrieben, die per Transaktion Änderungen in einer DWG-Datei vornimmt. Wenn ich die Funktion direkt per Kommando aufgerufen habe, klappt alles wunderbar! Wenn ich sie allerdings von einem modalen Fenster aus aufgerufen habe, gab es immer eine eLockViolation-Ausnahme:

Eine Ausnahme (erste Chance) des Typs “Autodesk.AutoCAD.Runtime.Exception” ist in AcdbMgd.dll aufgetreten.
Autodesk.AutoCAD.Runtime.Exception: eLockViolation

Zum Glück hat Sebastian eine Lösung im CAD-Forum gefunden:

wenn eine Funktion aus dem Form (eigentlich ohne AutoCAD-Befehl) gestartet wird, dann muss die Funktion dafür das Document vor Zugriff von anderen Befehlen sperren.

Das Sperren passiert mit der LockDocument-Eigenschaft des Dokument-Objektes:

Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices

Public Class TestForm
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim oActiveDoc As Document = Application.DocumentManager.MdiActiveDocument

        Using oAcadDocLock As DocumentLock = oActiveDoc.LockDocument
            Using oTransaction As Transaction = oActiveDoc.TransactionManager.StartTransaction
                '...
                '...
                '...
                oTransaction.Commit()
            End Using
        End Using
    End Sub
End Class
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.EditorInput

Public Class TextAutoCadAddIn
    <CommandMethod("test4")> _
    Public Sub Test()
        Application.ShowModelessDialog(New TestForm())
    End Sub
End Class