DOBON.NET DOBON.NETプログラミング掲示板過去ログ

構造体プロパティをデザイナで編集したい

環境/言語:[VB2008]
分類:[.NET]

お世話になります。VB勉強中の者です。
テキストボックスを継承してLocationプロパティに似たものを作ろうと思い、
以下のようにクラスと構造体を作成しました。

Public Structure XY
Dim x As Integer
Dim y As Integer
End Structure

Public Class TextBoxEx
Inherits TextBox

Private _XY As XY

Public Property POS() As XY
Get
Return _XY
End Get
Set(ByVal value As XY)
_XY = value
End Set
End Property
End Class


POSプロパティ自体は正常動作しているようですが、
デザイナ画面のプロパティウィンドウから編集できません。
(プロパティ名がグレーになり、値の欄も[ルート名前空間].XYと表示されるだけ)

Locationプロパティのようにデザイナ上で編集したいのですが、
どのような手順が必要なのでしょうか、そもそもできないのでしょうか、
よろしくお願いいたします。
■No27482に返信(花道さんの記事)
> テキストボックスを継承してLocationプロパティに似たものを作ろうと思い、
X,Y座標だけを管理するなら、XY 構造体を新たに作るのではなく、
System.Drawing.Point 構造体をそのまま使った方が良いかも。

> POSプロパティ自体は正常動作しているようですが、
> デザイナ画面のプロパティウィンドウから編集できません。
「プロパティを展開できるようにする」の項を参照してみてください。
http://dobon.net/vb/dotnet/control/propertygrid.html#expandable
■No27485に返信(魔界の仮面弁士さんの記事)
魔界の仮面弁士さん、ありがとうございます。
> System.Drawing.Point 構造体をそのまま使った方が良いかも。
実際に作りたいのはx,yではないのですが、説明の便宜上このようなサンプルになりました。

教えていただいたページ、うっかり読み流しておりました。
内容をコピーして試したところ編集はできるようになりましたが、項目の展開ができません。

そこで構造体の定義を以下のように変えました。
(Propertyに変更。ExpandableObjectConverterXYはExpandableObjectConverterを継承したもの)
<TypeConverter(GetType(ExpandableObjectConverterXY))> _
Public Structure XY
Private _x As Integer
Private _y As Integer

Public Property X() As Integer
Get
Return _x
End Get
Set(ByVal value As Integer)
_x = value
End Set
End Property

Public Property Y() As Integer
Get
Return _y
End Get
Set(ByVal value As Integer)
_y = value
End Set
End Property
End Structure

これで項目の展開もできるようになりました。
しかしプロパティをデザイナから編集してもビルドすると値が「0,0」に戻ってしまいます。

試しにPublic StructureをPublic Class と書き換えると、
編集も値の保持もできました。

構造体で値も保持する方法はあるのでしょうか?
またPropertyにしないとデザイナには出ないものなんでしょうか?
■No27488に返信(花道さんの記事)
> しかしプロパティをデザイナから編集してもビルドすると値が「0,0」に戻ってしまいます。
> 試しにPublic StructureをPublic Class と書き換えると、
> 編集も値の保持もできました。

まず、値型と参照型の違いについては把握しておられますでしょうか。

 Dim 参照型 = Me.Button1
 参照型.Text = "aaaa"

 Dim 値型 = Me.Location
 値型.X = 123

この場合、Button1.Text は変化しますが、Location.X は変化しませんね。


> 構造体で値も保持する方法はあるのでしょうか?
可能です。

実際、Size プロパティ/Size 構造体や
Location プロパティ/Point 構造体は、
デザイナで修正できますよね。

まず、その構造体は Serializable に設定されていますでしょうか。
また、型コンバータークラスのコードは、どのように記述されましたか?
もしかして、TextBoxEx.POS プロパティの欄が、
[ルート名前空間].XY のままになっていませんか?

# Size の場合には、System.Drawing.SizeConverter で処理され、
# Location では System.Drawing.PointConverter で処理されています。


> またPropertyにしないとデザイナには出ないものなんでしょうか?
コードエディタへの表示であれば、ご存知のようにフィールドでも表示されますが、
「PropertyGrid コントロール」に表示させるなら、基本的にはプロパティしか表示されません。
(Browsable 属性や EditorBrowsable 属性にもよりますが)

PropertyGrid にプロパティ以外を表示させたいのであれば、TypeConverter で
GetProperties メソッドを通じて、メンバーを動的プロパティとして
公開するという手法もありますが、通常はプロパティにした方が良いでしょう。
■No27490に返信(魔界の仮面弁士さんの記事)
> まず、値型と参照型の違いについては把握しておられますでしょうか。
わかっているつもりでしたが、なぜLocationプロパティが保存されるのか疑問でした。

結局、構造体に<Serializable()>をつけて解決しました。
Point構造体を調べると、やはり<Serializable>がついていました。

丁寧に教えていただいて勉強になりました。ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板