主婦と.NETと犬のぶろぐ

奥様 と プログラム と お犬様 の 楽しい日常

目次

Blog 利用状況

ニュース

書庫

日記カテゴリ

Panel(System.Windows.Forms.Panel)

Panel といっても何か遊ぼうと思うと、今まで遊んだ GroupBox なんかと似たり寄ったりになってしまうので
『限定したコントロールとその派生コントロールしか受け付けない Panel』を作る試みをしてみました。

ジェネリックとコンストラクタで型を指定するやつまでできたとこで
えムナウさんに他にいい方法がないですかねぇと相談したところ、
「プロパティは?」
っていう事で、プロパティでも実装しましたが、
プロパティでやるんだったらデザイナからどう変更させるかってのを考えないといけないので
面倒なので 文字列 で入力にしました。

文字列で入力だと型のチェックとか結構めんどかったです...。
enum も考えましたが、イマイチ汎用性にかけるかなぁと思ったんです。
でも文字列は明らかに使いにくいっす。何かいい方法がないかなー。

■参考文献
Panel クラス

■実行画像
今回も何も面白いこと無いです。BorderStyle で遊んでみただけ。
Panel

Public Class PanelTest

Const PANEL_NAME As String = "Panel1"
Private Sub PanelTest_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ' Panel.Controls に Add する型を限定する試み '' RadioButton の追加しか許可しない Panel その 1 Dim p1 As MyPanel(Of RadioButton) = New MyPanel(Of RadioButton) With p1 .Name = PANEL_NAME .Location = New Point(10, 10) .Size = New Size(200, 60) .BackColor = Color.LightBlue .BorderStyle = BorderStyle.None End With Me.Controls.Add(p1)
Dim rdoFujiko As RadioButton = New RadioButton() With rdoFujiko .Location = New Point(10, 10) .Text = "ふじこ" End With p1.Controls.Add(rdoFujiko) Dim rdoEden As RadioButton = New MyRadioButton() With rdoEden .Location = New Point(10, 30) .Text = "えでん" End With p1.Controls.Add(rdoEden) Try p1.Controls.Add(New ComboBox()) ' 作為的に発生 Catch ex As ArgumentException System.Diagnostics.Debug.WriteLine(ex.Message) End Try
'' RadioButton の追加しか許可しない Panel その 2 Dim p2 As MyPanel2 = New MyPanel2(GetType(RadioButton)) With p2 .Location = New Point(10, 90) .Size = New Size(200, 60) .BackColor = Color.LightYellow .BorderStyle = BorderStyle.FixedSingle End With Me.Controls.Add(p2) Try p2.Controls.Add(New TextBox()) ' 作為的に発生 Catch ex As ArgumentException System.Diagnostics.Debug.WriteLine(ex.Message) End Try
'' RadioButton の追加しか許可しない Panel その 3 Dim p3 As MyPanel3 = New MyPanel3() With p3 .TypeString = GetType(RadioButton).FullName .Location = New Point(10, 170) .Size = New Size(200, 60) .BackColor = Color.LightSalmon .BorderStyle = BorderStyle.Fixed3D End With Me.Controls.Add(p3) Try p3.Controls.Add(New ListBox()) ' 作為的に発生 Catch ex As ArgumentException System.Diagnostics.Debug.WriteLine(ex.Message) End Try End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim pnl As MyPanel(Of RadioButton) = DirectCast(Me.Controls(PANEL_NAME), MyPanel(Of RadioButton)) ' For Each で回す For Each r As RadioButton In pnl.Controls System.Diagnostics.Debug.WriteLine(r.Text & ":" & r.Checked.ToString()) Next End Sub End Class
' こいつはただ継承しただけ Public Class MyRadioButton Inherits RadioButton End Class
' ジェネリックを使う ' (デザイナで操作不可) Public Class MyPanel(Of T As System.Windows.Forms.Control) Inherits System.Windows.Forms.Panel
Protected Overrides Sub OnControlAdded(ByVal e As System.Windows.Forms.ControlEventArgs) If TypeOf e.Control Is T Then MyBase.OnControlAdded(e) Else MyBase.Controls.Remove(e.Control) Throw New ArgumentException(e.Control.GetType.FullName & ":このパネルに追加するコントロールは " & _ GetType(T).FullName & " またはその派生クラスでなければなりません") End If End Sub End Class
' コンストラクタで型指定 ' (デザイナで操作可能・しかしデザイナで貼り付けた場合は通常の Panel と何ら変わり無い) Public Class MyPanel2 Inherits System.Windows.Forms.Panel
Private m_Type As Type = GetType(System.Windows.Forms.Control)
Public Sub New(ByVal t As Type) MyBase.New() If Not IsBasedOnValidClass(t, GetType(System.Windows.Forms.Control)) Then Throw New ArgumentException("Control を継承した型でなければなりません") Me.m_Type = t End Sub
Protected Overrides Sub OnControlAdded(ByVal e As System.Windows.Forms.ControlEventArgs) If IsBasedOnValidClass(e.Control.GetType(), Me.m_Type) Then MyBase.OnControlAdded(e) Else MyBase.Controls.Remove(e.Control) Throw New ArgumentException(e.Control.GetType.FullName & ":このパネルに追加するコントロールは " & _ Me.m_Type.FullName & " またはその派生クラスでなければなりません") End If End Sub
Private Function IsBasedOnValidClass(ByVal t As Type, ByVal validBaseType As Type) As Boolean If t Is validBaseType Then Return True If t.BaseType Is Nothing Then Return False Return IsBasedOnValidClass(t.BaseType, validBaseType) End Function End Class
' プロパティで型指定 ' (デザイナで操作可能・しかし TypeString に何も指定しない場合は通常の Panel と何ら変わり無い) Public Class MyPanel3 Inherits System.Windows.Forms.Panel
Private m_typeString As String = GetType(System.Windows.Forms.Control).FullName Private m_type As Type = GetType(System.Windows.Forms.Control)
< System.ComponentModel.Browsable(True), System.ComponentModel.ReadOnly(False), _ System.ComponentModel.Description("追加を許可するコントロールの型を FullName で指定します") > _ Public Property TypeString() As String Get Return Me.m_typeString End Get Set(ByVal value As String) If String.IsNullOrEmpty(value) Then Throw New ArgumentException("値を Null にする事はできません") Dim tp As Type = Nothing ' 自身のアセンブリから型を検索 tp = System.Reflection.Assembly.GetExecutingAssembly.GetType(value, False) If tp Is Nothing Then ' なければ次に System.Windows.Forms.dll より型を検索 Dim foundControl As Object = GetType(System.Windows.Forms.Control).Assembly.CreateInstance(value, False) If Not foundControl Is Nothing Then tp = foundControl.GetType() End If If tp Is Nothing Then Throw New ArgumentException("型の文字列に誤りがあります") If Not IsBasedOnValidClass(tp, GetType(System.Windows.Forms.Control)) Then Throw New ArgumentException("Control を継承した型でなければなりません") Me.m_type = tp Me.m_typeString = value End Set End Property
Protected Overrides Sub OnControlAdded(ByVal e As System.Windows.Forms.ControlEventArgs) If IsBasedOnValidClass(e.Control.GetType(), Me.m_type) Then MyBase.OnControlAdded(e) Else MyBase.Controls.Remove(e.Control) Throw New ArgumentException(e.Control.GetType.FullName & ":このパネルに追加するコントロールは " & _ Me.m_type.FullName & " またはその派生クラスでなければなりません") End If End Sub
Private Function IsBasedOnValidClass(ByVal t As Type, ByVal validBaseType As Type) As Boolean If t Is validBaseType Then Return True If t.BaseType Is Nothing Then Return False Return IsBasedOnValidClass(t.BaseType, validBaseType) End Function End Class

投稿日時 : 2007年3月5日 13:19

Feedback

No comments posted yet.
タイトル  
名前  
Url
コメント