MS Access 中的 .Net 用户控件
Posted
技术标签:
【中文标题】MS Access 中的 .Net 用户控件【英文标题】:.Net usercontrol in MS Access 【发布时间】:2010-12-06 10:48:20 【问题描述】:借助Interrop toolkit 或简单的ActiveX,可以通过COM 创建可在VB6/MS Access 表单上使用的.Net UserControls。
这很有效,除了一个主要的痛苦:resizing。
您无法在运行时调整窗体上的控件大小。 将控件锚定到表单的相对两侧会使其在每次调整表单大小时都会增长,即使您缩小了表单...
似乎没有任何方法可以驯服这种行为:
在 .Net 中,任何通过代码调整 UserControl 大小的尝试都会失败。 在 MS Access 中,用户控件也不能通过代码调整大小。显然,一个解决方案可能是wrap the .Net Usercontrol in a VB6 usercontrol。 不幸的是,除了不得不使用另一个包装器和更多的临时代码之外,VB6 IDE 不再可用......
有没有办法解决这个问题?
【问题讨论】:
【参考方案1】:我不确定为什么 MS Access 和 VB6 的行为不同,但我找到了一个使用 .Net Interop 和 C# 的工作解决方案。使用 VB.Net 应该也能正常工作。
使用以下条目扩展 IInteropUserControl 接口:
void ResizeThis(int width, int height);
实现ResizeThis函数:
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);
在 MS Access 中,使用适当的宽度和高度参数调用 ResizeThis 函数。
还有另一个奇怪的行为。在 Access 表单中的每个记录移动中,UserControl 都会缩小一些像素。我通过重写 SetBoundsCore 函数并实现属性 LockResizing 解决了这个问题。当不应调整 UserControl 的大小时,此属性将分配为 true。
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;
UserControl 已使用 MS Access 2010 和 2016 (Office 365) 进行了测试。
【讨论】:
【参考方案2】:解决这个问题比预期的要复杂。每次你拿着解决方案时,它都会从你手中溜走......
VB MSDN 论坛中记录了一个简单的解决方案:Interop UserControl in MSAccess。 不完美,但比我找到的那个更简单。
主要问题是 Access 会擦除比控件更大的区域。 如果控件锚定在右边缘和下边缘,这不是问题,否则,您可以在子窗体或选项卡控件页面中使用控件,而不显示选项卡,使其充当容器。
【讨论】:
到底为什么你认为你需要这样做?它似乎过于复杂并且可能不稳定/不可靠。如果您需要在 Access 中构建前端,请使用 Access 提供的控件在 Access 中构建它,并学会忍受 Access 的限制。如果你这样做,你的白发就会少得多! .Net 与 Access 的互操作性在所有领域都运行良好,除了这个奇怪的问题。 恕我直言,David,将现有应用程序移至 .Net 并用可在 Access 应用程序和 .Net 中使用的 .Net 用户控件零碎地替换它是合理的版本。这使我们能够在应用程序上工作,而无需扩展和维护 2 组实现。 Access 并不是适用于所有应用程序类型的工具,通过简化前端代码并将其移至更丰富的环境,可以更好地发挥其实用性。【参考方案3】:我知道旧主题,但我有一个想法/解决方法,现在似乎正在工作。 不知道为什么....
在.net com 中控制
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
在访问表单中
Private Sub Form_Current()
MyControl1.ForceWidth = 800
MyControl1.ForceHeight = 600
MyControl1.Width = SignatureControl6.Width - 1 'force sending resize message
End Sub
仍在测试中,但看起来可能可行
【讨论】:
感谢您为本主题做出贡献。请带着你的结果回来,即使它们不起作用,它仍然可能会激励其他人最终得到一个可行的解决方案!以上是关于MS Access 中的 .Net 用户控件的主要内容,如果未能解决你的问题,请参考以下文章
在 MS Access 中使用 RegEx 将表单控件值替换为字符串
如何使用 vb.net 从 MS Access DB 表单中找出 Activex 控件