隐藏表单的DoubleBuffered属性而不使其无效

时间:2018-04-26 07:38:42

标签: vb.net visual-studio-2017

使用DECLARE nm VARCHAR2(50); age NUMBER; dep VARCHAR2(50); sal NUMBER; BEGIN pr_disp(nm,age,dep,sal); END; 我试图隐藏表单属性窗口中的Class属性但不使其无效。所以我在下面的代码示例中做了类似的事情......但是,DoubleBuffered属性仍然出现。那么,我们真的可以隐藏DoubleBuffered属性吗?如果是,我们怎么能这样做呢?

DoubleBuffered

1 个答案:

答案 0 :(得分:2)

您可以为表单创建自定义组件设计器,但是重新创建不可访问的System.Windows.Forms.Design.FormDocumentDesigner的功能是一项艰巨的任务。更简单的方法是使用Form的Site属性,因为我之前已经向您展示过访问设计器服务。

在这种情况下,您需要覆盖设计器主机的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显示中排除。

enter image description here