none
コントロールの継承におけるプロパティの初期値の変更 RRS feed

  • 質問

  • コントロールを継承する場合で、プロパティの初期値を変更したい場合みなさんどのようにされていますでしょうか?

    例えば以下のようにするだけだと「ComboBox.DropDownStyle」の既定値は「DropDown」なので

    「デザイナ」において「DropDown」を設定することが出来なくなりますよね?

    ※シリアライズされなくなるので(「Form.InitializeComponent」に記載されなくなる)

    Public Class ComboBoxOne
        Inherits ComboBox
    
        Public Sub New()
            MyBase.New()
    
            Me.DropDownStyle = ComboBoxStyle.DropDownList
        End Sub
    
    End Class

    「Overridable」なメンバは「Overrides」で「DefaultValue」や「ShouldSerializeHoge」で設定、

    「DropDownStyle」などのそうでないメンバは「Shadows」で全て同様に全て定義していくしかないのでしょうか?

    Public Class ComboBoxTwo
        Inherits ComboBox
    
        Public Sub New()
            MyBase.New()
    
            Me.DropDownStyle = ComboBoxStyle.DropDownList
        End Sub
    
        <DefaultValue(ComboBoxStyle.DropDownList)>
        Public Shadows Property DropDownStyle As ComboBoxStyle
            Get
                Return MyBase.DropDownStyle
            End Get
            Set(value As ComboBoxStyle)
                MyBase.DropDownStyle = value
            End Set
        End Property
    
    End Class

    何かこうするべきだとか、私はこのようにしているという良い方法があれば教えて頂ければと思います。

    よろしくお願いします。

    ★以下追加ですが、こういう方法でもいけるかと思うのですがいかがなものなのでしょうか?

    Public Class ComboBoxThree
        Inherits ComboBox
    
        Public Sub New()
            MyBase.New()
        End Sub
    
        Protected Overrides Sub InitLayout()
            MyBase.InitLayout()
    
            If Me.DesignMode Then
                Me.DropDownStyle = ComboBoxStyle.DropDownList
            End If
        End Sub
    
    End Class

    • 編集済み g_shin 2019年6月5日 3:50 追記
    2019年6月5日 3:26

回答

  • 既定値(default value) ではなく、初期値(initial value)さえ設定できれば良いのであれば、DesignerAttribute 属性を割り当てることができます。

    '追加の参照設定: System.Design.dll
    Imports System.Collections
    Imports System.ComponentModel
    Imports System.Windows.Forms
    Imports System.Windows.Forms.Design
    
    <Designer(GetType(ComboBoxTwo.ComboBoxTwoDesigner))>
    Partial Public Class ComboBoxTwo
        Inherits ComboBox
    
    #Region "Designer クラス"
        Friend Class ComboBoxTwoDesigner
            Inherits ControlDesigner
            Public Overrides Sub InitializeNewComponent(defaultValues As IDictionary)
                MyBase.InitializeNewComponent(defaultValues)
                With DirectCast(Control, ComboBoxTwo)
                    .DropDownStyle = ComboBoxStyle.DropDownList
                End With
            End Sub
            Protected Overrides Sub PreFilterProperties(properties As IDictionary)
                MyBase.PreFilterProperties(properties)
                properties("DropDownStyle") = CreateTemplateProperty(Of ComboBoxStyle)("DropDownStyle", "DropDownList")
            End Sub
            Private Function CreateTemplateProperty(Of T)(propName As String, defaultValue As String) As PropertyDescriptor
                Return TypeDescriptor.CreateProperty(GetType(ComboBoxTwo), propName, GetType(T), New DefaultValueAttribute(GetType(ComboBoxTwo), defaultValue))
            End Function
        End Class
    #End Region
    End Class
    2019年6月5日 6:16

すべての返信

  • 既定値(default value) ではなく、初期値(initial value)さえ設定できれば良いのであれば、DesignerAttribute 属性を割り当てることができます。

    '追加の参照設定: System.Design.dll
    Imports System.Collections
    Imports System.ComponentModel
    Imports System.Windows.Forms
    Imports System.Windows.Forms.Design
    
    <Designer(GetType(ComboBoxTwo.ComboBoxTwoDesigner))>
    Partial Public Class ComboBoxTwo
        Inherits ComboBox
    
    #Region "Designer クラス"
        Friend Class ComboBoxTwoDesigner
            Inherits ControlDesigner
            Public Overrides Sub InitializeNewComponent(defaultValues As IDictionary)
                MyBase.InitializeNewComponent(defaultValues)
                With DirectCast(Control, ComboBoxTwo)
                    .DropDownStyle = ComboBoxStyle.DropDownList
                End With
            End Sub
            Protected Overrides Sub PreFilterProperties(properties As IDictionary)
                MyBase.PreFilterProperties(properties)
                properties("DropDownStyle") = CreateTemplateProperty(Of ComboBoxStyle)("DropDownStyle", "DropDownList")
            End Sub
            Private Function CreateTemplateProperty(Of T)(propName As String, defaultValue As String) As PropertyDescriptor
                Return TypeDescriptor.CreateProperty(GetType(ComboBoxTwo), propName, GetType(T), New DefaultValueAttribute(GetType(ComboBoxTwo), defaultValue))
            End Function
        End Class
    #End Region
    End Class
    2019年6月5日 6:16
  • >魔界の仮面弁士さん

    返信どうもありがとうございます。

    「DesignerAttribute」を使用するほうがまっとうな気がしますね。

    初期値を「DropDownStyle = DropDownList」とすることによって、デザイン上で「太字(シリアライズされる)」ことは別に気にしない

    (むしろ変えている事が分かる方がいい)場合は「PreFilterProperties」のオーバーライドはなくてよいですよね?

    ちなみに

    Private Function CreateTemplateProperty(Of T)(propName As String, defaultValue As String) As PropertyDescriptor
        Return TypeDescriptor.CreateProperty(GetType(ComboBoxTwo), propName, GetType(T), New DefaultValueAttribute(GetType(T), defaultValue))
    End Function
    ですかね


    2019年6月5日 7:27
  • デザイン上で「太字(シリアライズされる)」ことは別に気にしない(むしろ変えている事が分かる方がいい)場合は「PreFilterProperties」のオーバーライドはなくてよいですよね?

    太字のままでよいのなら、InitializeNewComponent のみを実装すれば良さそうですね。

    ちなみに

    ですかね

    申し訳ありません。投稿直前にコードを整理しているウチに壊してしまったようで…。
    意図は伝わったようで何よりです。

    Return TypeDescriptor.CreateProperty(Control.GetType(), propName, GetType(T), New DefaultValueAttribute(GetType(T), defaultValue))

    2019年6月5日 8:05
  • >魔界の仮面弁士さん

    いえいえ、大変参考になりました。

    今後はこの方法で考えていこうと思います。どうもありがとうございます。

    2019年6月5日 8:25