Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8901

イベントハンドラまで対応したコントロール配列を作る

$
0
0

只今絶賛VB6からVB.NET (VS2017)への移行作業中です。
移行作業で非互換となる機能の一つにコントロール配列があります。
Microsoft.VisualBasic.Compatibility.VB6互換ライブラリを使用すればいいのですが
Deprecatedというわけで使用禁止。

止む無くTextBoxのコントロール配列クラスを自作することとなりました。

目標は

publicWithEventsText1AsMicrosoft.VisualBasic.Compatibility.VB6.TextBoxArray

publicWithEventsText1AsMyLib.TextBoxArray

のように置き換えるだけで済むクラスを作りたいというものです。
ネット検索では次のようなイベントハンドラにまで対応した例を見つけることが出来ませんでしたのでこれに対応するのが第一となります。

コントロール配列に対するイベントハンドラの例
'Text1はコントロール配列PrivateSubText1_KeyPress(senderAsObject,eAsKeyPressEventArgs)HandlesText1.KeyPressConsole.WriteLine("KeyPress")EndSub

クラスの定義は

Microsoft.VisualBasic.Compatibility.VB6.TextBoxArrayのドキュメント
https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.visualbasic.compatibility.vb6.textboxarray?view=netframework-4.8
および
Microsoft.VisualBasic.Compatibility.VB6.BaseControllArrayのドキュメント
https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.visualbasic.compatibility.vb6.basecontrolarray.hookupcontrolevents?view=netframework-4.8#Microsoft_VisualBasic_Compatibility_VB6_BaseControlArray_HookUpControlEvents_System_Object_

に準拠させるとして

Designer.vbファイルの中身

'中略publicWithEventsText1AsMicrosoft.VisualBasic.Compatibility.TextBoxArray'中略Me.Text1=NewMicrosoft.VisualBasic.Compatibility.TextBoxArray(Me.components)'中略CType(Me.Text1,System.ComponentModel.ISupportInitialize).BeginInit()'中略Me.Text1.SetIndex(Me._Text1_3,CType(3,Short))Me.Text1.SetIndex(Me._Text1_2,CType(2,Short))Me.Text1.SetIndex(Me._Text1_1,CType(1,Short))Me.Text1.SetIndex(Me._Text1_0,CType(0,Short))'中略CType(Me.Text1,System.ComponentModel.ISupportInitialize).EndInit()'中略

を参考に必要最小限に絞って作成した互換クラスが以下の通り
(ここに至るまで紆余曲折ありましたが全部省略)

BaseControlArray.cs
usingSystem;usingSystem.Collections;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Windows.Forms;namespaceMyLib{publicabstractclassBaseControlArray:Component,ISupportInitialize{// コントロール配列で管理するクラスをDictionaryに入れる// (Listとかに使用と思ったらインデックス-1で登録されてくるケースがあったので// Dictionaryにしました。)protectedDictionary<int,Control>items=newDictionary<int,Control>();//  コントロール配列内のコントロール数を返します。publicshortCount(){returnchecked((short)this.items.Count);}// 何もしないがこれがないとコンパイルエラーpublicvoidBeginInit(){}// 何もしないがこれがないとコンパイルエラーpublicvoidEndInit(){}// 気持ちの問題かprotectedoverridevoidDispose(booldisposing){if(disposing){items.Clear();}base.Dispose(disposing);}// 必要かどうか迷ったが入れておくpublicshortLBound(){return0;}// 必要かどうか迷ったが入れておくpublicshortUBound(){return(short)(items.Count-1);}publicIEnumeratorGetEnumerator(){returnitems.GetEnumerator();}}}
TextBoxArray.cs
usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Windows.Forms;namespaceMyLib{[ProvideProperty("Index",typeof(TextBox))]publicclassTextBoxArray:BaseControlArray,IExtenderProvider{// コンストラクタの中で何かする必要はなかったpublicTextBoxArray(){}// コンストラクタの中で何かする必要はなかったpublicTextBoxArray(IContainerContainer){}// KeyPressイベントハンドラpubliceventKeyPressEventHandlerKeyPress;// 与えられたこのコントロール配列に入れることが出来るかどうかを返すpublicboolCanExtend(objectextendee){returnextendeeisTextBox;}// コントロール配列の型を返すprotectedTypeGetControlInstanceType(){returntypeof(TextBox);}// コントロール配列にコントロールを登録publicvoidSetIndex(TextBoxitem,shortindex){items[index]=item;// コントロール配列のイベントを個々のコントロールに結び付けるif(KeyPress!=null)item.KeyPress+=KeyPress;}publicshortGetIndex(TextBoxitem){IEnumerator<KeyValuePair<int,Control>>enumerator=items.GetEnumerator();while(enumerator.MoveNext()){if(enumerator.Current.Value==item)return(short)enumerator.Current.Key;}return(short)0;}publicTextBoxthis[shortIndex]{get{return(TextBox)items[Index];}}}}

イベントハンドラはお好みで追加してください。
ほかの種類のコントロール配列はTextBoxArrayのコピペで行けると思います。

以上


Viewing all articles
Browse latest Browse all 8901

Trending Articles