是否可以在设计时更改属性属性的值? [英] Is it possible to change the value of a property attribute at design time?

查看:82
本文介绍了是否可以在设计时更改属性属性的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的User Control上有一个Property,它像这样在设计模式下隐藏了<​​/p>

I have a Property on my User Control that is hidden in design mode like so

<Browsable(False)>
Public Property MyProperty As Object

我想根据另一个Property的值将其更改为True.

What i would like to do is change it to True depending on the value of another Property.

类似

Private _otherProperty As Boolean
Public Property OtherProperty() As Boolean
    Get
        Return _otherProperty
    End Get
    Set(ByVal value As Boolean)
        _otherProperty = value
        If value = True Then
            'Set MyProperty Browsable Attribute True here
        Else
            'Set MyProperty Browsable Attribute False here
        End If
    End Set
End Property

这就是我的想法.

基本上我希望Property仅在另一个Property设置为True时在设计时可用,但找不到在设计模式下更改属性值的方法.

Basically i want a Property to only be available at design time when another Property is set to True but can't find a way to change the attribute value in design mode.

推荐答案

WinForm设计器的PropertyGrid中显示的属性通过 ICustomTypeDescriptor接口.

The properties displayed in the WinForm designer's PropertyGrid are managed via PropertyDescriptors. You can control the descriptors returned by the inspection mechanisms by a couple of different ways. A relatively simple (while tedious) way is have your class implement the ICustomTypeDescriptor Interface.

让我们假设您的usercontrol类定义如下:

Let us assume your usercontrol class is defined as follows:

Imports System.ComponentModel
Public Class DemoUC
  Public Sub New()
    InitializeComponent()
  End Sub

  <RefreshProperties(RefreshProperties.All)>
  Public Property OtherProperty As Boolean

  <Browsable(False)>
  Public Property MyProperty As String
End Class

注意 RefreshPropertiesAttribute 装饰OtherProperty.这将告诉PropertyGrid每次此属性更改时都拉动所有属性.这是必需的,以便在OtherProperty为true时显示MyProperty属性的逻辑起作用.

Notice the RefreshPropertiesAttribute decorating OtherProperty. This will tell the PropertyGrid to pull all properties each time this property changes. This is needed so that logic to display the MyProperty property when OtherProperty is true will work.

在另一个类文件中,添加以下实现ICustomTypeDescriptor Interface的部分类.

In another class file, add the following partial class that implements the ICustomTypeDescriptor Interface.

Imports System.ComponentModel

Partial Public Class DemoUC : Implements ICustomTypeDescriptor

  Public Function GetAttributes() As AttributeCollection Implements ICustomTypeDescriptor.GetAttributes
    Return TypeDescriptor.GetAttributes(Me, True)
  End Function

  Public Function GetClassName() As String Implements ICustomTypeDescriptor.GetClassName
    Return TypeDescriptor.GetClassName(Me, True)
  End Function

  Public Function GetComponentName() As String Implements ICustomTypeDescriptor.GetComponentName
    Return TypeDescriptor.GetComponentName(Me, True)
  End Function

  Public Function GetConverter() As TypeConverter Implements ICustomTypeDescriptor.GetConverter
    Return TypeDescriptor.GetConverter(Me, True)
  End Function

  Public Function GetDefaultEvent() As EventDescriptor Implements ICustomTypeDescriptor.GetDefaultEvent
    Return TypeDescriptor.GetDefaultEvent(Me, True)
  End Function

  Public Function GetDefaultProperty() As PropertyDescriptor Implements ICustomTypeDescriptor.GetDefaultProperty
    Return TypeDescriptor.GetDefaultProperty(Me, True)
  End Function

  Public Function GetEditor(editorBaseType As Type) As Object Implements ICustomTypeDescriptor.GetEditor
    Return TypeDescriptor.GetEditor(Me, editorBaseType, True)
  End Function

  Public Function GetEvents() As EventDescriptorCollection Implements ICustomTypeDescriptor.GetEvents
    Return TypeDescriptor.GetEvents(Me, True)
  End Function

  Public Function GetEvents(attributes() As Attribute) As EventDescriptorCollection Implements ICustomTypeDescriptor.GetEvents
    Return TypeDescriptor.GetEvents(Me, attributes, True)
  End Function

  Public Function GetProperties() As PropertyDescriptorCollection Implements ICustomTypeDescriptor.GetProperties
    Return GetProperties({})
  End Function

  Public Function GetProperties(attributes() As Attribute) As PropertyDescriptorCollection Implements ICustomTypeDescriptor.GetProperties
    Dim basePDs As New PropertyDescriptorCollection(Nothing, False)
    For Each pd As PropertyDescriptor In TypeDescriptor.GetProperties(Me, attributes, True)
      basePDs.Add(pd)
    Next
    If Me.DesignMode AndAlso Me.OtherProperty Then
      Dim pd As PropertyDescriptor = TypeDescriptor.GetProperties(Me, True).Cast(Of PropertyDescriptor).Where(Function(desc As PropertyDescriptor) desc.Name.Equals(NameOf(Me.MyProperty))).FirstOrDefault()
      If basePDs.Contains(pd) Then
        basePDs.Remove(pd)
      End If
      basePDs.Add(New BrowsableDescriptor(pd))
    End If
    Return basePDs
  End Function

  Public Function GetPropertyOwner(pd As PropertyDescriptor) As Object Implements ICustomTypeDescriptor.GetPropertyOwner
    Return Me
  End Function

  Class BrowsableDescriptor : Inherits PropertyDescriptor
    Private src As PropertyDescriptor
    Public Sub New(src As PropertyDescriptor)
      MyBase.New(src.Name, Nothing)
      Me.src = src
      Dim attribs As New List(Of Attribute)
      For Each att As Attribute In src.Attributes
        If TypeOf att Is BrowsableAttribute Then Continue For
        attribs.Add(att)
      Next
      attribs.Add(BrowsableAttribute.Yes)
      MyBase.AttributeArray = attribs.ToArray
    End Sub

    Public Overrides ReadOnly Property IsBrowsable As Boolean
      Get
        Return True
      End Get
    End Property

    Public Overrides ReadOnly Property ComponentType As Type
      Get
        Return src.ComponentType
      End Get
    End Property

    Public Overrides ReadOnly Property IsReadOnly As Boolean
      Get
        Return src.IsReadOnly
      End Get
    End Property

    Public Overrides ReadOnly Property PropertyType As Type
      Get
        Return src.PropertyType
      End Get
    End Property

    Public Overrides Sub ResetValue(component As Object)
      src.ResetValue(component)
    End Sub

    Public Overrides Sub SetValue(component As Object, value As Object)
      src.SetValue(component, value)
    End Sub

    Public Overrides Function CanResetValue(component As Object) As Boolean
      Return src.CanResetValue(component)
    End Function

    Public Overrides Function GetValue(component As Object) As Object
      Return src.GetValue(component)
    End Function

    Public Overrides Function ShouldSerializeValue(component As Object) As Boolean
      Return src.ShouldSerializeValue(component)
    End Function
  End Class

End Class

大多数实现只返回基本的TypeDescriptor提供的内容. GetProperties函数是在其中实现的逻辑,用于使用可浏览的逻辑替换MyProperty属性的不可浏览的PropertyDescriptor.

The majority of the implementation just returns what the base TypeDescriptor would provide. The GetProperties function is where the logic is implemented to replace the non-browsable PropertyDescriptor for the MyProperty property with a browsable one takes place.

这是代码编译后,DemoUC控件将在PropertyGrid中显示如下.观察到MyProperty是根据OtherProperty的值显示/隐藏的.

Once this is code is compiled, the DemoUC control will display like this in the PropertyGrid. Observe that MyProperty is shown/Hidden based on the value of OtherProperty.

这篇关于是否可以在设计时更改属性属性的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆