デフォルト値とシリアライゼーション

カスタムコントロール作成入門講座中級編

初級編で作成した影付き文字列のサンプルコントロール、フォームに貼り付けた直後の状態でも、プロパティを右クリックすると次のようになっています。

20140106_192101

「リセット」が無効化されていますし、”GrayText”の文字は、変更があったことを知らせるボールド文字になっています。コードでは変数にデフォルト値を設定してますが、Visual Studioにはそれがわかりません。そのために上のような状態になるわけです。

では、Visual Studioにデフォルト値を伝えましょう。そのための一番簡単な方法は、DefaultValue属性を使うことです。

[DefaultValue(typeof(Color), "GrayText")]
public Color ShadowColor
{ ... }

[DefaultValue(1)]
public int ShadowDepth
{ ... }
<DefaultValue(GetType(Color), "Gray.Text")> _
Public Property ShadowColor() As Color
...
End Property

<DefaultValue(1)> _
Public Property ShadowDepth() As Integer
...
End Property

ShadowDepthのように、数値や文字列などの単純な型の場合は、そのままデフォルト値を書けます。Colorのようなクラスの場合は、typeofやGetTypeを使用する必要があります。例えばFontの場合は次のようになります。

[DefaultValue(typeof(Font), "MS 明朝, 10, style=Bold")]
<DefaultValue(GetType(Font), "MS明朝, 10, style="Bold")> _

クラスの場合は、実は裏でType Converterというものが動いています。Type Converterは、実際の値と文字列との間を双方向に変換するメソッドです。ColorにはColorのType Converterが、FontにはFontのType Converterがあります。もちろん自作することもできますが、それは次回紹介します。

デフォルト値を設定するかしないかということは、実はもう一つ重要なことと関係があります。オブジェクトのシリアライゼーションです。シリアライゼーションというのは、おおざっぱに言うと、オブジェクトの状態をファイルなどに保存できるようにすることです。逆に、復元することをデシリアライゼーションと言います。

C#なら、Form1.Designer.csの、自動生成されるInitializeComponentメソッドにその様子を見ることができます。※VB.NETでも見る方法があるのでしょうか?

// 
// customControl11
// 
this.customControl11.Location = new System.Drawing.Point(20, 20);
this.customControl11.Name = "customControl11";
this.customControl11.ShadowColor = System.Drawing.SystemColors.GrayText;
this.customControl11.ShadowDepth = 1;
this.customControl11.Size = new System.Drawing.Size(75, 23);
this.customControl11.TabIndex = 1;
this.customControl11.Text = "customControl11";

上のコードは、ShadowColorとShadowDepthにDefaultValue属性を設定する前の状態の時の、InitializeComponentメソッドの一部です。デフォルト値から変更があった、またはデフォルト値が不明なプロパティの情報をデシリアライズしています。プロパティの数が増え、使用するコントロールの数も増えてくると、このことがより重要な意味を持ってきます。

まとめると、DefaultValueはプロパティにデフォルト値を設定し、Visual Studioはデフォルト値を利用して、そのプロパティをシリアライズするかどうかを決めます。

実はシリアライズするかどうかを決めさせる方法がもう一つあります。ShouldSerializePropertyNameメソッドです。PropertyNameの部分には実際のプロパティ名が入ります。シリアライズする必要がある時にtrueを返します。ShadowColorプロパティの場合は次のようになります。

public bool ShouldSerializeShadowColor()
{
    return _shadowColor != SystemColors.GrayText;
}

public void ResetShadowColor()
{
    _shadowColor = SystemColors.GrayText;
}
Public Function ShouldSerializeShadowColor() As Boolean
    Return _shadowColor <> SystemColors.GrayText
End Function

Public Sub ResetShadowColor()
    _shadowColor = SystemColors.GrayText
End Sub

ResetPropertyNameは「リセット」を選択した時に呼ばれます。これらはメソッドなので、複雑な判定が必要な場合に使える方法です。

« »

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

« »