LinkLabel を派生して付加情報を追加する - Visual C# 2008

SPECIAL


リンクラベル毎に付加情報を設定する

C# のリンクラベルで、クリックイベントに独自の引数を渡すことができないかというお話があったので、それについて少し調べてみることにしました。

まず、Visual Studio 2008 で LinkLabel のクリックイベントに対するハンドラーを生成しても、引数として渡されるものは、自分自身を示す object と LinkLabelLinkClickedEventArgs だけになります。

ここに自由に値を渡せる可能性があるとすれば、自分自身である object に対してだけとなると思われます。

 

この object に格納されているアドレスがどのリンクラベルに該当するかを判定して、それを頼りに別の配列等に格納しておいた値を参照する方法もあるかと思いますが、オブジェクト指向であればやはり object それぞれに対して固有の値を設定してそれを参照する形にしたいところです。

そういう経緯で実験として、LinkLabel の派生クラスを作成して、それに任意の値を持たせてそれをクリック時に表示させてみようと思います。

 

今回は Visual Studio 2008 の C# を使ってたせいか、自動的にいろいろとやってくれて便利でした。もしかするとそれより前のバージョンの場合、手作業でフォームの XML を書き換えたりなどしなければいけない必要があるかもしれないので注意してください。

 

LinkLabel の派生クラスを作成する

派生クラスの実装

まず、プロジェクトに新規クラスを追加します。

ここでは通常の C# クラスを作成します。今回は "LinkLabelEx" という名前のクラスを作成しておくことにしました。

クラスを作成したら、まずはそれを "LinkLabel" から継承させます。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace WindowsFormsApplication1

{

class LinkLabelEx : System.Windows.Forms.LinkLabel

{

}

}

LinkLabel を継承したら、この "LinkLabelEx" が独自に持つ変数を定義します。

今回はとりあえず、何らかの数値を保持する "options" という Int32 型の値を持てるようにしようと思います。もちろんここは String 型でも、その他いくつでも実装できます。

下記では少し冗長な記載になっていますが、やっていることは "options" プロパティに代入された値を "m_options" 属性に保存し、"options" プロパティを参照した場合に "m_options" 属性の値を返すというコードになっています。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace WindowsFormsApplication1

{

class LinkLabelEx : System.Windows.Forms.LinkLabel

{

/// <summary>

/// コンストラクターで m_options 属性を初期化しておきます。

/// </summary>

public LinkLabelEx()

{

m_options = 0;

}

 

/// <summary>

/// options プロパティの値を保持する属性です。

/// </summary>

private Int32 m_options;

 

/// <summary>

/// options プロパティ値を取得または設定します。

/// </summary>

public Int32 options

{

get

{

return m_options;

}

 

set

{

m_options = value;

}

}

}

}

ちなみに、上記ではコンストラクターで "m_options" の値を 0 に初期化していますが、ここの値がフォームに "LinkLabelEx" を貼り付けたときの初期の値になるようです。

using System.ComponentModel を使用して、プロパティー宣言 "public Int32 options" の直前に "[DefaultValue(typeof(Int32), "0")]" を記載することで、フォームエディターにこのプロパティーの既定値がいくつであるかを明示することも可能でしたが、これは単に、フォームエディターで既定値以外を設定した場合に太字になるかどうか程度のようでしたので、お好みで宣言すれば良いかと思います。

 

ここまで実装できたら、いったんビルドしておきましょう。

ビルドしておかないと、Visual Studio 2008 のフォームエディターが今回作成した "LinkLabelEx" を認識することが出来ない様子です。また、ビルドすることで、フォームエディターのツールボックス内にも "LinkLabelEx" が表示されるようになります。

 

Form 上に "LinkLabelEx" を配置する

"LinkLabelEx" のビルドが成功したら、フォームエディターのツールボックスで "LinkLabelEx" が選択可能になっていると思います。

 

もし選択できるようになっていない場合は、"LinkLabelEx" が正しくビルドできていないのかもしれません。

場合によっては、ここで "タイプ 'SOLUTIONNAME.LinkLabelEx' が見つかりません。このタイプを含むアセンブリが参照されているかどうかを確認してください。このタイプが開発プロジェクトの一部である場合、プロジェクトが正常にビルドされたかどうかも確認してください。" というメッセージが表示されているかもしれませんが、その場合もまだ自作の "LinkLabelEx" がビルドされていないと思うので、ビルドを一回成功させてあげれば解消すると思います。

 

ツールボックスに無事 "LinkLabelEx" が表示されたら、後はこれを従来通り、フォームに貼り付けます。

今回は 3 つばかり、フォームに張ってみることにしました。

このようにしたら、例えば "linkLabelEx1" を選択して、そのプロパティーを表示させます。

すると、"LinkLabelEx" に実装したプロパティ "options" もここで設定できるようになっていました。

後はここで、リンクラベル毎に "options" プロパティーの値を設定してあげれば、それぞれのラベルが個別の値を持つことができるようになりました。

 

クリックされたラベルの "options" の値を取得してみる

たとえば、"LinkLabelEx" を貼り付けたフォーム上で、次のようなコードを実装してみます。

private void onLinkExClicked(object sender, LinkLabelLinkClickedEventArgs e)

{

LinkLabelEx p_linklabel = (LinkLabelEx)sender;

 

MessageBox.Show(String.Format("OPTIONS={0}", p_linklabel.options));

}

ここでは、クリックされたオブジェクトを "LinkLabelEx" 型にキャストして、そこから "options" プロパティーの値を取得しています。

そしてそれを、ダイアログボックスで画面に表示するということを行うメソッドです。

 

これを、フォーム上に貼り付けた "LinkLabelEx" コントロールの "LinkClicked" イベントに設定してみます。

そうすると、リンクがクリックされたときに、リンク毎に設定された "options" プロパティーの値を取得して、それを画面に表示されるようになりました。

他のコントロールでも同様にして独自の情報を追加できると思うので、このような感じでコントロール毎に固有の情報を持たせてあげれば、プログラムコードが論理的にすっきりするので、開発効率や保守性の面でも、個人的にはおすすめです。