如何使用嵌套属性创建用户控件 [英] How to create user control with nested properties

查看:136
本文介绍了如何使用嵌套属性创建用户控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在设计一个Windows窗体控件,我需要在我的控件中创建嵌套属性

例如:

我想要字体大小,字体颜色,以及Font

解决方案

下的font-family嵌套属性如果要执行此操作,则必须创建具有所需属性的类。这个类应该是你的新属性的类型。



示例:

  Imports  System.ComponentModel 
Imports System.ComponentModel.Design

< TypeConverter ( GetType (PaddingDefinition.Converter))>
公共 PaddingDefinition
<说明( 文本到左侧的距离)>
属性作为 整数
获取
返回 _left
结束 获取
设置 ByVal 作为 整数
如果 _left<> value 然后
_left = value
RaiseEvent 已更改()
< span class =code-keyword>结束 如果
结束 设置
结束 属性
私有 _left 整数 = 5

<说明( 文本到右侧的距离)>
属性正确正如 整数
获取
返回 _right
结束 获取
设置 ByVal 作为 整数
如果 _right<> value 然后
_right = value
RaiseEvent 已更改()
< span class =code-keyword>结束 如果
结束 设置
结束 属性
私有 _right 作为 整数 = 5


公开 活动已更改()


Sub ()
结束 Sub

Sub ByVal left 作为 整数 ByVal 作为 整数
_left = left
_right = right
RaiseEvent 已更改()
结束 Sub


覆盖 功能 toString()作为 字符串
返回 Left.ToString.Trim& ;& Right.ToString.Trim
结束 功能


函数 toPadding()作为填充
返回 填充(_left, 0 ,_ right, 0
结束 功能

< span class =code-keyword> Sub fromPadding(setPadding As Padding)
_left = setPadding.Left
_right = setPadding 。
RaiseEvent 已更改()
结束 Sub



公共 转换器
继承 ExpandableObjectConverter

公共 重载 覆盖 功能 CanConvertFrom( ByVal context As ITypeDescriptorContext, ByVal sourceType As Type) 作为 布尔
如果 sourceType GetType String 然后
返回 True
退出 功能
结束 如果
' Konvertierung von string zulassen
返回 MyBase 。 CanConvertFrom(context,sourceType)
结束 功能

公共 重载 覆盖 功能 ConvertFrom( ByVal context 作为 ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value 作为 对象作为 对象
如果值。 GetType GetType String 然后
' Konvertierung von string
Dim s As 字符串 = CType (值,字符串
Dim sa As String ()= Split(s, ;
如果 sa .Length> = 2 然后
Dim p1,p2 As 整数
如果 整数。 TryParse(sa( 0 ),p1) AndAlso Integer .TryParse(sa( 1 ),p2)然后
返回 PaddingDefinition(p1,p2)
退出 功能
结束 如果
结束 如果
抛出 FormatException()
结束 如果

返回 MyBase .ConvertFrom(context,文化,价值)
结束 功能

结束

结束 < span class =code-keyword> Class





现在使用它:



<类别( 设计),Description( 定义控件内的距离)> 
< DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
< DefaultValue( 5; 5)>
阴影 属性填充作为 PaddingDefinition
获取
返回 my_Padding
结束 获取
设置 ByVal As PaddingDefinition)
my_Padding = value
End 设置
结束 属性

私有 WithEvents my_Padding 作为 PaddingDefinition

< RefreshProperties(RefreshProperties.All)>
私有 Sub Padding_Changed()句柄 my_Padding.Changed
' 你想用它做什么...
结束 Sub





我希望这会给你一个想法...





编辑:

我看到(也许有点迟到)问题指向C#。

我的解决方案适用于VB。 8)

但是 - 它显示了它是如何完成的......


没有嵌套属性这样的概念。这没有任何意义。



如果你的财产是 class 或<$ c,你会有一种筑巢$ c> struct ,它本身可以包含其他 struct 的属性,等等。



你没有解释什么会在控制中嵌套。您需要描述UI行为来解释它。我不知道你是否真的需要 PropertyGrid ,但如果你这样做,那么定制它是相对困难的。这个想法是:你应该以不同的形式表示你的对象或对象树:一些代表你的对象的不同类型的中间体;此表示对象(surrogate类型)应实现接口 System.ComponentModel.ICustomTypeDescriptor

https://msdn.microsoft.com/en-us/library/system.componentmodel.icustomtypedescriptor% 28v = vs.110%29.aspx [ ^ ]。



-SA


您可以使用Visual Studio使用的相同属性网格控件,但在您自己的窗体中 - 请参阅这篇文章 [ ^ ]对于e xample。

I am designing a windows forms control and I need to create nested properties in my control
for example:
I want to have font-size, font-color, and font-family nested properties under Font

解决方案

If you want to do this, you have to create a class which has the needed Properties. This class should be the Type of your "new Property".

Example :

Imports System.ComponentModel
Imports System.ComponentModel.Design

<TypeConverter(GetType(PaddingDefinition.Converter))>
Public Class PaddingDefinition
    <Description("distance of text to the left side")>
    Property Left As Integer
        Get
            Return _left
        End Get
        Set(ByVal value As Integer)
            If _left <> value Then
                _left = value
                RaiseEvent Changed()
            End If
        End Set
    End Property
    Private _left As Integer = 5

    <Description("distance of text to the right side")>
    Property Right As Integer
        Get
            Return _right
        End Get
        Set(ByVal value As Integer)
            If _right <> value Then
                _right = value
                RaiseEvent Changed()
            End If
        End Set
    End Property
    Private _right As Integer = 5


    Public Event Changed()


    Sub New()
    End Sub

    Sub New(ByVal left As Integer, ByVal right As Integer)
        _left = left
        _right = right
        RaiseEvent Changed()
    End Sub


    Overrides Function toString() As String
        Return Left.ToString.Trim & ";" & Right.ToString.Trim
    End Function


    Function toPadding() As Padding
        Return New Padding(_left, 0, _right, 0)
    End Function

    Sub fromPadding(setPadding As Padding)
        _left = setPadding.Left
        _right = setPadding.Right
        RaiseEvent Changed()
    End Sub

    

    Public Class Converter
        Inherits ExpandableObjectConverter

        Public Overloads Overrides Function CanConvertFrom(ByVal context As ITypeDescriptorContext, ByVal sourceType As Type) As Boolean
            If sourceType Is GetType(String) Then
                Return True
                Exit Function
            End If
            'Konvertierung von string zulassen
            Return MyBase.CanConvertFrom(context, sourceType)
        End Function

        Public Overloads Overrides Function ConvertFrom(ByVal context As ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object) As Object
            If value.GetType Is GetType(String) Then
                'Konvertierung von string
                Dim s As String = CType(value, String)
                Dim sa As String() = Split(s, ";")
                If sa.Length >= 2 Then
                    Dim p1, p2 As Integer
                    If Integer.TryParse(sa(0), p1) AndAlso Integer.TryParse(sa(1), p2) Then
                        Return New PaddingDefinition(p1, p2)
                        Exit Function
                    End If
                End If
                Throw New FormatException()
            End If

            Return MyBase.ConvertFrom(context, culture, value)
        End Function

    End Class

End Class



and now the use of it :

<Category("Design"), Description("defines the distances inside the control")>
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
<DefaultValue("5;5")>
Shadows Property Padding As PaddingDefinition
    Get
        Return my_Padding
    End Get
    Set(ByVal value As PaddingDefinition)
        my_Padding = value
    End Set
End Property

Private WithEvents my_Padding As New PaddingDefinition

<RefreshProperties(RefreshProperties.All)>
Private Sub Padding_Changed() Handles my_Padding.Changed
   ' whaz you want to do with it ...
End Sub



I hope this gives you an idea ...


Edit :
I have seen (perhaps a little to late) that the question points to C#.
My Solution is for VB. 8)
But nevertheless - it shows how it could be done ...


There is no such concept of "nested property". It just makes no sense.

You have a kind of nesting if your property is class or struct, which can itself has properties of some other class or struct, and so on.

You did not explain what would nesting "in Control" mean. You need to describe the UI behavior to explain that. I don't know if you really need PropertyGrid, but if you do, customizing it is relatively difficult. The idea is: you should represent your object or the object tree in different form: some intermediate of different type representing your object; this representation object ("surrogate" type) should implement the interface System.ComponentModel.ICustomTypeDescriptor:
https://msdn.microsoft.com/en-us/library/system.componentmodel.icustomtypedescriptor%28v=vs.110%29.aspx[^].

—SA


You can use the same property grid control that visual studio uses but in your own windows forms - see this article[^] for an example.


这篇关于如何使用嵌套属性创建用户控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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