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.
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.
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