Share via


カスタム コントロールのデザイン時プロパティ (Windows フォーム .NET)

この記事では、Visual Studio の Windows フォーム Visual Designer でコントロールのプロパティを処理する方法について説明します。

すべてのコントロールは、基底クラス System.Windows.Forms.Control から次のような多くのプロパティを継承します。

コントロールを作成するときに、新しいプロパティを定義し、デザイナーでの表示方法を制御できます。

重要

.NET 7 と .NET 6 用のデスクトップ ガイド ドキュメントは作成中です。

プロパティを定義する

コントロールによって定義された get アクセサーを持つパブリック プロパティは、Visual Studio の [プロパティ] ウィンドウに自動的に表示されます。 プロパティが set アクセサーも定義している場合は、[プロパティ] ウィンドウでプロパティを変更できます。 ただし、BrowsableAttribute を適用することで、[プロパティ] ウィンドウでプロパティを明示的に表示や非表示にできます。 この属性は、表示されるかどうかを示す 1 つのブール値パラメーターを使用します。 属性の詳細については、「属性 (C#)」または「属性の概要 (Visual Basic)」を参照してください。

[Browsable(false)]
public bool IsSelected { get; set; }
<Browsable(False)>
Public Property IsSelected As Boolean

[注] 文字列との間で暗黙的に変換できない複合プロパティには、型コンバーターが必要です。

シリアル化されたプロパティ

コントロールに設定されたプロパティが、デザイナーの分離コード ファイルにシリアル化されます。 これは、プロパティの値が既定値以外に設定されているときに発生します。

デザイナーは、プロパティの変更を検出すると、コントロールのすべてのプロパティを評価し、値がプロパティの既定値と一致しないプロパティをすべてシリアル化します。 プロパティの値が、デザイナーの分離コード ファイルにシリアル化されます。 既定値は、シリアル化する必要があるプロパティ値をデザイナーが判断するのに役立ちます。

既定の値

プロパティは、DefaultValueAttribute 属性を適用するか、プロパティのクラスにプロパティ固有の ResetShouldSerialize メソッドが含まれているときに、既定値を持つとみなされます。 属性の詳細については、「属性 (C#)」または「属性の概要 (Visual Basic)」を参照してください。

既定値を設定すると、次が有効になります。

  • プロパティが既定値から変更されている場合は、[プロパティ] ウィンドウに視覚的に示されます。
  • プロパティを右クリックし、 [リセット] を選択すると、プロパティを既定値に戻すことができます。
  • デザイナーを使用すると、より効率的なコードが生成されます。

プロパティがプリミティブ型などの単純型を使用する場合は、プロパティに DefaultValueAttribute を適用することで既定値を設定できます。 ただし、この属性を持つプロパティは、その割り当てられた値で自動的に開始されません。 プロパティのバッキング フィールドを同じ既定値に設定する必要があります。 このプロパティは、宣言またはクラスのコンストラクターで設定できます。

プロパティが複合型であるか、デザイナーのリセットとシリアル化の動作を制御するときは、クラスの Reset<PropertyName>ShouldSerialize<PropertyName> メソッドを定義します。 たとえば、コントロールが Age プロパティを定義すると、メソッドの名前は ResetAgeShouldSerializeAge になります。

重要

プロパティに DefaultValueAttribute を適用するか、Reset<PropertyName>ShouldSerialize<PropertyName> の両方のメソッドを指定するかのどちらかにしてください。 両方の使用はしないでください。

プロパティは、プロパティ名を右クリックして [リセット] を選択することで、[プロパティ] ウィンドウで既定値に "リセット" できます。

プロパティ グリッドの [コンテキスト メニュー項目のリセット]。

[プロパティ]>右クリック>[リセット] というコンテキスト メニュー オプションが使用可能なのは、次のときです。

  • プロパティに DefaultValueAttribute 属性が適用されていて、プロパティの値が属性の値と一致しない。
  • プロパティのクラスが、ShouldSerialize<PropertyName> なしで Reset<PropertyName> メソッドを定義している。
  • プロパティのクラスが Reset<PropertyName> メソッドを定義していて、ShouldSerialize<PropertyName> が true を返す。

DefaultValueAttribute

プロパティの値が DefaultValueAttribute が提供する値と一致しない場合、プロパティは変更されたとみなされ、[プロパティ] ウィンドウでリセットできます。

重要

この属性は、対応する Reset<PropertyName>ShouldSerialize<PropertyName> メソッドを持つプロパティでは使用しないでください。

次のコードは、既定値が North の列挙型と、既定値が 10 の整数の 2 つのプロパティを宣言しています。

[DefaultValue(typeof(Directions), "North")]
public Directions PointerDirection { get; set; } = Directions.North;

[DefaultValue(10)]
public int DistanceInFeet { get; set; } = 10;
<DefaultValue(GetType(Directions), "North")>
Public Property PointerDirection As Directions = Directions.North

<DefaultValue(10)>
Public Property DistanceInFeet As Integer = 10

Reset と ShouldSerialize

前述したように、Reset<PropertyName>ShouldSerialize<PropertyName> メソッドは、プロパティのリセット動作だけでなく、値が変更され、デザイナーの分離コード ファイルにシリアル化される必要があるかどうかの判断についても指針を示す機会を提供します。 両方のメソッドは連携して動作するため、もう一方なしで片方を定義しないようにする必要があります。

重要

DefaultValueAttribute を持つプロパティに対して、Reset<PropertyName>ShouldSerialize<PropertyName> メソッドを作成しないでください。

Reset<PropertyName> が定義されているときは、[プロパティ] ウィンドウに、そのプロパティの [リセット] コンテキスト メニュー オプションが表示されます。 [リセット] を選択すると、Reset<PropertyName> メソッドが呼び出されます。 [リセット] コンテキスト メニュー オプションは、ShouldSerialize<PropertyName> メソッドから返される内容に応じて有効または無効になります。 ShouldSerialize<PropertyName>true を返すと、プロパティがその既定値から変更され、分離コード ファイルにシリアル化される必要があることを示し、[リセット] コンテキスト メニュー オプションを有効にします。 false が返されると、[リセット] コンテキスト メニュー オプションが無効になり、プロパティによって設定されたコードが分離コードから削除されます。

ヒント

どちらのメソッドも、コントロールのパブリック API を構成しないように、プライベート スコープで定義可能で、そのようにする必要があります。

次のコード スニペットは、Direction という名前のプロパティを宣言します。 このプロパティのデザイナー動作は、ResetDirectionShouldSerializeDirection メソッドによって制御されます。

public Directions Direction { get; set; } = Directions.None;

private void ResetDirection() =>
    Direction = Directions.None;

private bool ShouldSerializeDirection() =>
    Direction != Directions.None;
Public Property Direction As Directions = Directions.None

Private Sub ResetDirection()
    Direction = Directions.None
End Sub

Private Function ShouldSerializeDirection() As Boolean
    Return Direction <> Directions.None
End Function

型コンバーター

型コンバーターは通常、ある型を別のものに変換しますが、プロパティ グリッドやその他のデザイン時コントロールに対する文字列から値への変換も提供します。 文字列から値への変換を使用すると、これらのデザイン時コントロールで複合プロパティを表すことができます。

ほとんどの組み込みデータ型 (数値、列挙型など) には、文字列から値への変換を提供し、検証チェックを実行する既定の型コンバーターがあります。 既定の型コンバーターは System.ComponentModel 名前空間にあり、変換される型に基づく名前が付けられています。 コンバーターの型名は、形式 {type name}Converter を使用します。 たとえば、StringConverterTimeSpanConverterInt32Converter などです。

型コンバーターは、[プロパティ] ウィンドウと並んでデザイン時に頻繁に使用されます。 型コンバーターは、TypeConverterAttribute を使用してプロパティまたは型に適用できます。

TypeConverterAttribute がプロパティで宣言されているとき、[プロパティ] ウィンドウはコンバーターを使用してそのプロパティを文字列値として表示します。 TypeConverterAttribute が型で宣言されているとき、[プロパティ] ウィンドウはその型のすべてのプロパティに対してコンバーターを使用します。 型コンバーターは、デザイナーの分離コード ファイルのプロパティ値のシリアル化にも役立ちます。

型エディター

プロパティの型が組み込みまたは既知の型のとき、[プロパティ] ウィンドウはプロパティの型エディターを自動的に使用します。 たとえば、ブール値は TrueFalse の値を持つコンボ ボックスとして編集され、DateTime 型はカレンダー ドロップダウンを使用します。

重要

.NET Framework 以降、カスタム型エディターが変更されました。 詳細については、「.NET Framework (Windows Form .NET) 以降にデザイナーが変更されます」を参照してください。