- PR -

複数のカスタムコントロールで共通のコードをまとめたい

投稿者投稿内容
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-10-27 01:18
引用:

敢えて共通化するのであれば、私なら以下の方法を取るかと思います。
たぶん実際には使える場面は少ないと思いますし、しないと思います。



WinForms のコントロールに関しては、よっぽど使い回しの効く汎用的な機能でも無い限り、派生で何か機能追加を行うのはあまりわりに合わないんですよね。

なので、すでにコメントが出ているように、特定のプロジェクトでしか使わないような機能追加は、IExtenderProvider による拡張プロバイダを使うのが安上がりです。

拡張プロバイダの実装:
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/cpguide/html/cpconImplementingExtenderProvider.asp
nakaP
大ベテラン
会議室デビュー日: 2005/09/27
投稿数: 138
お住まい・勤務地: 高知
投稿日時: 2007-10-28 00:46
引用:

IExtenderProvider による拡張プロバイダ


こういうものがあるのですね。
まだ.Netを始めて間もないので、初めて聞きました。
ありがとうございます、勉強になります。

まだご提示のMSDNのページを読み流した程度ですが、スレ主の状況には丁度良いものではないでしょうか。

[追記]
手前の私の例はスパゲティの元になりますね・・・。
まだ理解できてないですが、素直にComponentを使うほうがいいですねorz

[ メッセージ編集済み 編集者: J.J. 編集日時 2007-10-29 15:20 ]
ume
会議室デビュー日: 2007/10/25
投稿数: 6
投稿日時: 2007-10-29 08:52
ありがとうございます。
拡張プロバイダを試してみたいと思います。
ume
会議室デビュー日: 2007/10/25
投稿数: 6
投稿日時: 2007-11-05 23:42
大変遅くなってしまいましたが、
完成したソースコードです。
拡張プロバイダを利用して作成する方法も試してみたのですが、
今回はどうしてもコントロール自体にイベントを追加した状態で使用したかったので
以下のような方法にしてみました。

<カスタムコントロール>
Imports System.Drawing
Imports CommonControl.ControlEvent
''' <summary>
''' TextBoxを継承したクラス
''' </summary>
''' <remarks></remarks>
Public Class CustomTextBox
#Region " 変数"
''' <summary>変更する色</summary>
Private _focusColor As Color = Color.Empty
#End Region
#Region " コンストラクタ"
''' <summary>
''' コンストラクタ
''' </summary>
''' <remarks></remarks>
Public Sub New()

' この呼び出しは、Windows フォーム デザイナで必要です。
InitializeComponent()

' InitializeComponent() 呼び出しの後で初期化を追加します。

'必要なイベントを追加
AddHandler Me.Enter, AddressOf OnEnter
AddHandler Me.Leave, AddressOf OnLeave
AddHandler Me.KeyDown, AddressOf OnKeyDown

End Sub
#End Region

#Region " Property"
''' <summary>
''' フォーカス取得時背景色
''' </summary>
''' <value>背景色</value>
''' <returns>背景色</returns>
''' <remarks></remarks>
Public Property FocusColor() As Color
Get
Return _focusColor
End Get
Set(ByVal value As Color)
_focusColor = value
End Set
End Property
#End Region
End Class

<イベントクラス>
Imports System.Drawing
Imports System.Windows.Forms

''' <summary>
''' 共通イベントクラス
''' </summary>
''' <remarks></remarks>
Friend Class ControlEvent

#Region " 変数"
''' <summary>元の色</summary>
Private Shared _originalBackColor As Color
''' <summary>変更する色</summary>
Private Shared _focusColor As Color = Color.Empty

#End Region

#Region " event"

#Region " フォーカス取得時の背景色制御用イベント群"
''' <summary>
''' コントロールのEnterイベント
''' </summary>
''' <param name="sender">イベント発生元コントロール</param>
''' <param name="e">System.EventArgs</param>
''' <remarks></remarks>
Friend Shared Sub OnEnter(ByVal sender As Object, ByVal e As System.EventArgs)
Dim ctrl As Control
Dim t As Type
Dim prop As Reflection.PropertyInfo = Nothing

ctrl = CType(sender, Control)

'対象のコントロールのFocusColorプロパティの値をGet
t = ctrl.GetType()
prop = t.GetProperty("FocusColor")

If prop IsNot Nothing Then
_focusColor = CType(t.InvokeMember("FocusColor", Reflection.BindingFlags.GetProperty, Nothing, sender, Nothing), Color)
End If

'現在の背景色を保存し、目立つ色に変更する
_originalBackColor = ctrl.BackColor

If _focusColor = Color.Empty Then
_focusColor = DefaultFocusedBackColor
End If
ctrl.BackColor = _focusColor

End Sub

''' <summary>
''' コントロールのLeaveイベント
''' </summary>
''' <param name="sender">イベント発生元コントロール</param>
''' <param name="e">System.EventArgs</param>
''' <remarks></remarks>
Friend Shared Sub OnLeave(ByVal sender As Object, ByVal e As System.EventArgs)
Dim ctrl As Control

ctrl = CType(sender, Control)

'背景色とフォントを元に戻す
ctrl.BackColor = _originalBackColor
End Sub
#End Region

#Region " Enter時のフォーカス移動用イベント群"
''' <summary>
''' コントロールのKeyDownイベント
''' </summary>
''' <param name="sender">イベント発生元コントロール</param>
''' <param name="e">System.Windows.Forms.KeyEventArgs</param>
''' <remarks></remarks>
Friend Shared Sub OnKeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs)
Dim ctrl As Control

ctrl = CType(sender, Control)

'Enterキーが押されたときにフォーカスの移動を行う
If e.KeyCode = System.Windows.Forms.Keys.Enter Then
'テキストボックスの場合
If sender.GetType Is Type.GetType("CommonControl.TextBox") Then
Dim txtbox As TextBox

txtbox = CType(sender, TextBox)

'複数行入力可の場合処理、MybaseのKeyDownを実行
If txtbox.Multiline = True Then
Return
End If
End If

'フォーカス移動
Dim forward As Boolean = e.Modifiers <> Windows.Forms.Keys.Shift

ctrl.FindForm.SelectNextControl(ctrl, forward, True, True, True)

Return
End If

End Sub

#End Region
#End Region
End Class

また、カスタムコントロールとは関係ないのですが、
ご教示いただいた拡張プロバイダを利用してDrag&Dropの共通コンポーネントを
作成することができました。
大変役に立ちました。本当にありがとうございました。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-11-06 02:00
なぜリフレクションを使用しているのでしょう? ポリモーフィズムの概念の出番だと思います。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-11-06 02:06
それと、System.Type.GetType 'メソッド' ではなくて GetType 'ステートメント' を使いましょう。 文字列から型を生成してはコンパイル解決できないのでおいしくないです。

いきなり CType するのではなく TryCast ステートメントを利用しましょう。
イベント発生元でもないのに On ~ というメソッド名を書くと混乱しますね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
ume
会議室デビュー日: 2007/10/25
投稿数: 6
投稿日時: 2007-11-06 10:39
じゃんぬねっと様

ご指摘ありがとうございます。
知識不足な部分がありまして、理解できない部分があります。
お手数をおかけして申し訳ないのですが、詳しくご教示願えますでしょうか?

引用:
なぜリフレクションを使用しているのでしょう? ポリモーフィズムの概念の出番だと思います。


とのご指摘ですが、これはFocusColorのプロパティをカスタムコントロールに記述していることをおっしゃられているのでしょうか?
それとも、FocusColorのプロパティをイベントクラスでGetPropertyを使用して取得している部分のことでしょうか?
もしくはまったくの別の部分でしょうか??

FocusColorのプロパティはカスタムコントロールのプロパティウィンドウで設定したいので
カスタムコントロールに記述しています。
イベントクラスでのプロパティの取得は色々試したのですが、うまくいかず、
GetPropertyを使用して取得しておりますので良い方法があればご教示ください。

引用:
それと、System.Type.GetType 'メソッド' ではなくて GetType 'ステートメント' を使いましょう。


申し訳ありません。GetType 'ステートメント' を調べたのですが
情報を見つけることができませんでした。具体的にご教示願えますか?

TryCastについてはご指摘通り、修正いたしました。
以下が修正をしたソースコードです。

コード:
<イベントクラス> 
Imports System.Drawing 
Imports System.Windows.Forms 
Imports System.Reflection

''' <summary> 
''' 共通イベントクラス 
''' </summary> 
''' <remarks></remarks> 
Friend Class ControlEvent 

#Region " 変数" 
''' <summary>元の色</summary> 
Private Shared _originalBackColor As Color 
''' <summary>変更する色</summary> 
Private Shared _focusColor As Color = Color.Empty 

#End Region 

#Region " event" 

#Region " フォーカス取得時の背景色制御用イベント群" 
''' <summary> 
''' コントロールのEnterイベント 
''' </summary> 
''' <param name="sender">イベント発生元コントロール</param> 
''' <param name="e">System.EventArgs</param> 
''' <remarks></remarks> 
Friend Shared Sub xxxxEnter(ByVal sender As Object, ByVal e As System.EventArgs) 
    Dim ctrl As Control 
    Dim t As Type 
    Dim prop As PropertyInfo = Nothing 

    ctrl = TryCast (sender, Control) 

    if ctrl is nothing then
        'エラー処理
      Return
    end if

    '対象のコントロールのFocusColorプロパティの値をGet 
    t = ctrl.GetType() 
    prop = t.GetProperty("FocusColor") 

    If prop IsNot Nothing Then 
        _focusColor = CType(t.InvokeMember("FocusColor", BindingFlags.GetProperty, Nothing, sender, Nothing), Color) 
    End If 

    '現在の背景色を保存し、目立つ色に変更する 
    _originalBackColor = ctrl.BackColor 

    If _focusColor = Color.Empty Then 
        _focusColor = DefaultFocusedBackColor 
    End If 
    ctrl.BackColor = _focusColor 

End Sub 

''' <summary> 
''' コントロールのLeaveイベント 
''' </summary> 
''' <param name="sender">イベント発生元コントロール</param> 
''' <param name="e">System.EventArgs</param> 
''' <remarks></remarks> 
Friend Shared Sub xxxxLeave(ByVal sender As Object, ByVal e As System.EventArgs) 
Dim ctrl As Control 

    ctrl = TryCast (sender, Control) 

    if ctrl is nothing then
        'エラー処理
      Return
    end if

    '背景色とフォントを元に戻す 
    ctrl.BackColor = _originalBackColor 
End Sub 
#End Region 

#Region " Enter時のフォーカス移動用イベント群" 
''' <summary> 
''' コントロールのKeyDownイベント 
''' </summary> 
''' <param name="sender">イベント発生元コントロール</param> 
''' <param name="e">System.Windows.Forms.KeyEventArgs</param> 
''' <remarks></remarks> 
Friend Shared Sub xxxxKeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) 
Dim ctrl As Control 

    ctrl = TryCast (sender, Control) 

    if ctrl is nothing then
        'エラー処理
      Return
    end if

    'Enterキーが押されたときにフォーカスの移動を行う 
    If e.KeyCode = System.Windows.Forms.Keys.Enter Then 
        Dim txtbox As TextBox 

        txtbox = TryCast (sender, TextBox) 

        'テキストボックスの場合 
        If txtbox IsNot Nothing Then 
            '複数行入力可の場合処理、MybaseのKeyDownを実行 
            If txtbox.Multiline = True Then 
                Return 
            End If 
        End If 

        'フォーカス移動 
        Dim forward As Boolean = e.Modifiers <> Windows.Forms.Keys.Shift 

        ctrl.FindForm.SelectNextControl(ctrl, forward, True, True, True) 

        Return 
    End If 

End Sub 

#End Region 
#End Region 
End Class 






スキルアップ/キャリアアップ(JOB@IT)