Benutzer mit den meisten Antworten
Problem mit eingebettetem OCX (MsFlexGrid)

Frage
-
Hallo,
ich habe ein Problem mit einer von VB6 nach .NET migrierten Anwendung. Zur Anzeige von berichten wird in dieser Anwendung das MsFlexGrid-OCX verwendet. Das MsFlexGrid ist in ein User-Control eingebettet, von welchem weitere berichtsspezifische User-Controls abgeleitet sind. Die Anzeige der Berichte erfolgt in einem Formular welches die Auswahl eines spezifischen Berichts über Tab-Reiter ermöglicht. Auf jeder TabPage befindet sich ein User-Control mit dem eingebetteten MsFlexGrid-OCX. Prinzipiell funktioniert das ganz gut. Wenn jedoch im Formular nicht alle Tab-Reiter ausgewählt wurden wirft die Runtime beim Schließen des Formulars eine TargetInvocationException mit dem Hinweis dass fensterlose Controls nicht unterstützt werden. Da dieser Hinweis einen Bezug zum MsFlexGrid OCX hat geht meine Vermutung dahin, dass das OCX erst dann ein Fenster-Handle erzeugt, wenn es auf dem Bildschirm sichtbar wird. Hier der Stacktrace:
System.Reflection.TargetInvocationException: Der Fensterhandle für das Steuerelement AxMSFlexGrid konnte nicht abgerufen werden. Fensterlose ActiveX-Steuerelemente werden nicht unterstützt. ---> System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
bei System.Windows.Forms.AxHost.DoVerb(Int32 verb)
bei System.Windows.Forms.AxHost.MakeVisibleWithShow()
--- Ende der internen Ausnahmestapelüberwachung ---
bei System.Windows.Forms.AxHost.MakeVisibleWithShow()
bei System.Windows.Forms.AxHost.OnContainerVisibleChanged(Object sender, EventArgs e)
bei System.Windows.Forms.Control.OnVisibleChanged(EventArgs e)
bei System.Windows.Forms.ScrollableControl.OnVisibleChanged(EventArgs e)
bei System.Windows.Forms.Control.WmShowWindow(Message& m)
bei System.Windows.Forms.Control.WndProc(Message& m)
bei System.Windows.Forms.ScrollableControl.WndProc(Message& m)
bei System.Windows.Forms.ContainerControl.WndProc(Message& m)
bei System.Windows.Forms.UserControl.WndProc(Message& m)
bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
bei System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Ich habe versucht, diese Exception im Close-Event des Formulars abzufangen. Damit habe ich aber lediglich erreicht, dass die Exception später (nämlich beim Aufruf der Dispose() Methode durch den Garbage-Collector) auftritt. Dieses Verhalten tritt nur dann auf, wenn die Anwendung direkt ausgeführt wird. Läuft sie unter Kontrolle des Visual-Studio Debuggers, wird die Exception nur als First-Chance-Exception im Output-Fenster angezeigt.
Wir sind zwar dabei, das OCX durch ein anderes Control zu ersetzen, müssen aber bis Anfang nächste Woche eine Version der Anwendung ausliefern und haben bis dahin die Umstellung noch nicht beendet. Hat jemand eine Idee, wie das beschrieben Problem umgangen werden kann?
Vielen Dank im Voraus
Andreas Seibt- Verschoben Robert BreitenhoferModerator Donnerstag, 10. Juni 2010 12:21 VB6 Interop und Upgrade (aus:Visual Basic (ab Version 2002 / .NET))
Antworten
-
Hi Andreas,
bei Betrieb des DataGridView kannst du problemlos jede Zelle einzeln formatieren. Hier mal eine kleine Demo:
Option Infer On ' Only VB9 Option Strict On Public Class Form1 Private WithEvents dgv As New DataGridView With {.Dock = DockStyle.Fill} Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.Controls.AddRange(New Control() {dgv}) dgv.DataSource = (From tz In TimeZoneInfo.GetSystemTimeZones).ToList dgv.AutoResizeColumns() End Sub Private Sub dgv_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles dgv.CellFormatting If (e.ColumnIndex + e.RowIndex) Mod 5 = 0 Then e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleRight End If End Sub End Class
Das geht auch weiter über Font, Farben usw.
Im virtuellen Modus kannst du dann noch mehr Möglichkeiten.
--
Peter- Als Antwort vorgeschlagen Robert BreitenhoferModerator Sonntag, 13. September 2009 18:16
- Als Antwort markiert Robert BreitenhoferModerator Montag, 21. September 2009 19:02
Alle Antworten
-
Hi Andreas,
ich würde anstelle des MsFlexGrid sofort das DataGridView im ungebundenen oder virtuellen Modus nutzen. Da ist fast keine Anpassung erforderlich. Beim MSHFlexGrid wäre es etwas komplzierter.
Wenn das nicht möglich ist, dann würde ich die Instanzierung des AxMSFlexGrid auf der Tabpage erst beim Erhalt des Focus der Tabpage durchführen.
--
Peter -
Danke für die schnelle Antwort.
Leider ist weder die eine noch die andere Lösung schnell machbar. Das DataGridView-Control können wir nicht verwenden, da es nicht alle Formatierungsmöglichkeiten des MsFlexGrid hat (so habe ich z.B. keine Möglichkeit gefunden einzelne Zellen rechts- bzw. linksbündig zu formatieren). Da die beiden Berichtsformulare der Anwendung jeweils über 20 Tab-Reiter haben, ist auch die zweite Lösung mit einigem Codierungsaufwand verbunden. Mittlerweile haben wir begonnen, da MsFlexGrid auf das Farpoint Spread Control umzustellen (unter anderem, weil die Berichte nach Excel exportiert werden müssen was mit diesem Control durch ein einfaches SaveToExcel() erledigt ist). Da ich sowohl für die Aufbereitung der Berichte als auch für die User-Controls eine Klassenhierarchie erstellt habe hält sich der Aufwand in Grenzen. Mittlerweile bin ich guter Dinge, dass die Umstellung bis morgen abgeschlossen ist und ich meinen Termin einhalten kann.
Gruß
Andreas
-
Hi Andreas,
bei Betrieb des DataGridView kannst du problemlos jede Zelle einzeln formatieren. Hier mal eine kleine Demo:
Option Infer On ' Only VB9 Option Strict On Public Class Form1 Private WithEvents dgv As New DataGridView With {.Dock = DockStyle.Fill} Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.Controls.AddRange(New Control() {dgv}) dgv.DataSource = (From tz In TimeZoneInfo.GetSystemTimeZones).ToList dgv.AutoResizeColumns() End Sub Private Sub dgv_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles dgv.CellFormatting If (e.ColumnIndex + e.RowIndex) Mod 5 = 0 Then e.CellStyle.Alignment = DataGridViewContentAlignment.MiddleRight End If End Sub End Class
Das geht auch weiter über Font, Farben usw.
Im virtuellen Modus kannst du dann noch mehr Möglichkeiten.
--
Peter- Als Antwort vorgeschlagen Robert BreitenhoferModerator Sonntag, 13. September 2009 18:16
- Als Antwort markiert Robert BreitenhoferModerator Montag, 21. September 2009 19:02