2010-12-06 13 views
3

Es ist möglich, .Net UserControls zu erstellen, die auf einem VB6/MS Access-Formular über COM mit Hilfe der Interrop toolkit oder als einfache ActiveX verwendet werden können..Net usercontrol in MS Access

Dies funktioniert ziemlich gut, außer einem großen Schmerz: resizing.

Sie können die Größe des Steuerelements im Formular zur Laufzeit nicht ändern.
Verankerung der Steuerung an den gegenüberliegenden Seiten der Form, die sie jedes Mal, wenn Sie das Formular wachsen macht die Größe, auch wenn Sie das Formular reduzieren ...

Es scheint keinen Weg, um dieses Verhalten zu zähmen:

  • Von .Net schlägt jeder Versuch, das UserControl durch Code zu ändern, fehl.
  • Von MS Access kann das Benutzersteuerelement auch nicht durch Code geändert werden.

Anscheinend kann eine Lösung zu wrap the .Net Usercontrol in a VB6 usercontrol sein. Unglücklicherweise muss die VB6-IDE nicht mehr verwendet werden, da noch ein weiterer Wrapper und mehr Ad-hoc-Code benötigt wird ...

Gibt es eine Möglichkeit, dieses Problem zu lösen?

Antwort

1

Ich bin mir nicht sicher, warum MS Access und VB6 verhält sich differentl y, aber ich fand eine funktionierende Lösung mit .Net Interop mit C#. Mit VB.Net sollte es auch funktionieren.

  1. Erweiterte IInteropUserControl Schnittstelle mit dem folgenden Eintrag:

    Hohlraum ResizeThis (int Breite, Höhe int);

  2. Umsetzung der ResizeThis Funktion:

    public void ResizeThis(int width, int height) 
    { 
        this.UpdateBounds(Left, Top, width, height); 
        this.SetBounds(0, 0, width + 1, height + 1, BoundsSpecified.Width | BoundsSpecified.Height); 
    } 
    
  3. In MS Access rufen die ResizeThis Funktion mit den entsprechenden Breiten- und Höhenparameter.

  4. Es gibt ein anderes merkwürdiges Verhalten. Bei jeder Datensatzbewegung im Access-Formular verkleinert sich das UserControl um einige Pixel. Ich habe dieses Problem gelöst, indem ich die SetBoundsCore-Funktion überschrieben und eine Eigenschaft LockResizing implementiert habe. Diese Eigenschaft wird mit true angegeben, wenn das UserControl nicht in der Größe geändert werden soll.

    protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified) 
    { 
        if (_LockResizing) 
         throw new Exception(); 
    
        base.SetBoundsCore(x, y, width, height, specified); 
    } 
    
    public bool LockResizing 
    { 
        get { return _LockResizing; } 
        set { _LockResizing = value; } 
    } 
    

Die Usercontrol wurde mit MS Access 2010 und 2016 (Office 365) getestet.

1

Das Lösen dieses Problems ist komplexer als erwartet. Jedes Mal, wenn Sie eine Lösung halten, rutscht es durch Ihre Hände ...

Eine einfache Lösung ist in den VB MSDN Foren dokumentiert: Interop UserControl in MSAccess.
Nicht perfekt, aber einfacher als die, die ich gefunden habe.

Das Hauptproblem ist, dass Access einen Bereich löscht, der größer ist als das Steuerelement.
Wenn das Steuerelement an den rechten und unteren Kanten verankert ist, ist das kein Problem, andernfalls können Sie das Steuerelement in einem Unterformular oder einer Registerkarte Steuerelement ohne die Registerkarten verwenden, so dass es als ein Container fungiert.

+0

Warum in der Welt denken Sie, dass Sie das tun müssen? Es scheint übermäßig kompliziert und wahrscheinlich instabil/unkalkulierbar. Wenn Sie Ihr Frontend in Access erstellen müssen, erstellen Sie es in Access mithilfe der von Access bereitgestellten Steuerelemente und lernen Sie, mit den Einschränkungen von Access zu leben. Sie werden viel weniger graue Haare haben, wenn Sie dies tun! –

+2

.Net Interoperabilität mit Access funktioniert ziemlich gut in allen Bereichen, mit Ausnahme dieses seltsamen Problems. –

+3

Bei allem Respekt David, es ist nicht unzumutbar, eine vorhandene Anwendung auf .Net zu verschieben, indem Sie sie stückweise durch .Net-Benutzersteuerelemente ersetzen, die sowohl in der Access-App als auch in der .Net-Version verwendet werden können. Dies ermöglicht es uns, an der Anwendung zu arbeiten, ohne 2 Implementierungssätze erweitern und warten zu müssen. Access ist nicht das richtige Werkzeug für alle Anwendungstypen, und hier ist es sinnvoller, den Code des Frontends zu vereinfachen und in eine reicher Umgebung zu verschieben. –

1

Altes Thema Ich weiß, aber ich habe eine Idee/arbeiten um das scheint im Moment zu arbeiten.
Sie Warum nicht wissen ....

Mit in .net com Steuerung

Private _ForceWidth As Integer = 0 
Private _ForceHeight As Integer = 0 

Public Property ForceWidth As Integer 
    Get 
     Return _ForceWidth 
    End Get 
    Set(value As Integer) 
     _ForceWidth = value 
    End Set 
End Property 


Public Property ForceHeight As Integer 
    Get 
     Return _ForceHeight 
    End Get 
    Set(value As Integer) 
     _ForceHeight = value 
    End Set 
End Property 



Private Sub MyControl_Resize(sender As Object, e As EventArgs) Handles MyBase.Resize 
    If ForceWidth > 0 Then 
     Me.Width = ForceWidth 
    End If 
    If ForceHeight > 0 Then 
     Me.Height = ForceHeight 
    End If 
End Sub 

In Acces Formular

Private Sub Form_Current() 
    MyControl1.ForceWidth = 800 
    MyControl1.ForceHeight = 600 
    MyControl1.Width = SignatureControl6.Width - 1 'force sending resize message 
End Sub 

noch in dem Test, sieht aber wie es könnte funktionieren

+0

Vielen Dank für Ihren Beitrag zu diesem Thema. Bitte kommen Sie mit Ihren Ergebnissen zurück, selbst wenn sie nicht funktionieren, kann es immer noch jemanden dazu inspirieren, zu einer funktionierenden Lösung zu kommen! –