vb.net - 隐藏表单的 DoubleBuffered 属性而不使其不起作用
问题描述
使用Class
我试图DoubleBuffered
从表单的属性窗口中隐藏该属性,但不使其不起作用。所以我在下面的代码示例中做了类似的事情......但是,DoubleBuffered
属性仍然出现。那么,我们真的可以隐藏DoubleBuffered
财产吗?如果可以,我们该怎么做呢?
Imports System.ComponentModel
Imports System.ComponentModel.Design
Public Class MyForm
Inherits Form
<Browsable(False)>
Public Overloads Property DoubleBuffered As Boolean
Get
Return MyBase.DoubleBuffered
End Get
Set(ByVal value As Boolean)
MyBase.DoubleBuffered = value
End Set
End Property
Public Sub New()
Me.DoubleBuffered = True
End Sub
End Class
解决方案
您可以为您的表单创建一个自定义组件设计器,但仅重新创建不可访问的功能是一项艰巨的任务System.Windows.Forms.Design.FormDocumentDesigner
。更简单的方法是使用我之前向您展示过的表单的站点属性来访问设计器服务。
在这种情况下,您需要覆盖设计器主机的ITypeDescriptorFilterService服务。该服务由设计者用于所有类型发现/过滤操作,并且不限于特定组件。
第一步是创建一个实现ITypeDescriptorFilterService
. 以下是一种这样的实现。它是一个通用实现,允许它过滤指定类型的组件并获取要从 PropertyGrid 显示中排除的属性名称列表。它需要的最后一项是对设计器宿主使用的现有服务的引用。
Friend Class FilterService(Of T) : Implements ITypeDescriptorFilterService
Private namesOfPropertiesToRemove As String()
Public Sub New(baseService As ITypeDescriptorFilterService, ParamArray NamesOfPropertiesToRemove As String())
Me.BaseService = baseService
Me.namesOfPropertiesToRemove = NamesOfPropertiesToRemove
End Sub
Public ReadOnly Property BaseService As ITypeDescriptorFilterService
Public Function FilterAttributes(component As IComponent, attributes As IDictionary) As Boolean Implements ITypeDescriptorFilterService.FilterAttributes
Return BaseService.FilterAttributes(component, attributes)
End Function
Public Function FilterEvents(component As IComponent, events As IDictionary) As Boolean Implements ITypeDescriptorFilterService.FilterEvents
Return BaseService.FilterEvents(component, events)
End Function
Public Function FilterProperties(component As IComponent, properties As IDictionary) As Boolean Implements ITypeDescriptorFilterService.FilterProperties
' ref: ITypeDescriptorFilterService Interface: https://msdn.microsoft.com/en-us/library/system.componentmodel.design.itypedescriptorfilterservice(v=vs.110).aspx
'
' The return value of FilterProperties determines if this set of properties is fixed.
' If this method returns true, the TypeDescriptor for this component can cache the
' results. This cache is maintained until either the component is garbage collected or the Refresh method of the type descriptor is called.
' allow other filters 1st chance to modify the properties collection
Dim ret As Boolean = BaseService.FilterProperties(component, properties)
' only remove properties if component is of type T
If TypeOf component Is T AndAlso Not (properties.IsFixedSize Or properties.IsReadOnly) Then
For Each propName As String In namesOfPropertiesToRemove
' If the IDictionary object does not contain an element with the specified key,
' the IDictionary remains unchanged. No exception is thrown.
properties.Remove(propName)
Next
End If
Return ret
End Function
End Class
表单中的示例用法:
Imports System.ComponentModel
Imports System.ComponentModel.Design
Public Class TestForm : Inherits Form
Private host As IDesignerHost
Private altTypeDescriptorProvider As FilterService(Of TestForm)
' spelling and character casing of removedPropertyNames is critical
' it is a case-sensative lookup
Private Shared removedPropertyNames As String() = {"DoubleBuffered"}
Public Overrides Property Site As ISite
Get
Return MyBase.Site
End Get
Set(value As ISite)
If host IsNot Nothing Then
UnwireDesignerCode()
End If
MyBase.Site = value
If value IsNot Nothing Then
host = CType(Site.GetService(GetType(IDesignerHost)), IDesignerHost)
If host IsNot Nothing Then
If host.Loading Then
AddHandler host.LoadComplete, AddressOf HostLoaded
Else
WireUpDesignerCode()
End If
End If
End If
End Set
End Property
Private Sub HostLoaded(sender As Object, e As EventArgs)
RemoveHandler host.LoadComplete, AddressOf HostLoaded
WireUpDesignerCode()
End Sub
Private Sub WireUpDesignerCode()
AddFilter()
End Sub
Private Sub UnwireDesignerCode()
If host IsNot Nothing Then
RemoveFilter()
End If
host = Nothing
End Sub
Private Sub AddFilter()
Dim baseFilter As ITypeDescriptorFilterService = CType(host.GetService(GetType(ITypeDescriptorFilterService)), ITypeDescriptorFilterService)
If baseFilter IsNot Nothing Then
' remove existing filter service
host.RemoveService(GetType(ITypeDescriptorFilterService))
' create our replacement service and add it to the host's services
altTypeDescriptorProvider = New FilterService(Of TestForm)(baseFilter, removedPropertyNames)
host.AddService(GetType(ITypeDescriptorFilterService), altTypeDescriptorProvider)
TypeDescriptor.Refresh(Me.GetType) ' force a type description rescan
End If
End Sub
Private Sub RemoveFilter()
If altTypeDescriptorProvider IsNot Nothing Then
host.RemoveService(GetType(ITypeDescriptorFilterService))
host.AddService(GetType(ITypeDescriptorFilterService), altTypeDescriptorProvider.BaseService)
altTypeDescriptorProvider = Nothing
End If
End Sub
End Class
现在,当您创建一个继承自 的表单时TestForm
,该DoubleBuffered
属性将从 PropertyGrid 显示中排除。
推荐阅读
- ruby-on-rails - 我需要帮助来构建这个 Rails 应用程序
- assembly - 用 MUL 代替 DIV,为什么会这样?
- python - 如果用户输入错误,则重新启动程序并询问用户是否要重新启动游戏
- javascript - 使用 Electron 将 Angular 项目(进行 RESP API 调用)转换为桌面应用程序
- reactjs - React Naive 在显示启动画面时加载图像
- django - Django 扩展管理主页 - 向内容区域添加元素
- java - 我如何将数据从 firebase 检索到 android listview 的顶部
- java - 动态添加芯片到芯片组
- python-3.x - 无法使用 send_keys python selenium 发送
- java - 我的世界插件 NoClassDefFoundError