C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[12]: 構造体プロパティをデザイナ自動生成コードでNew宣言させたい


(過去ログ 111 を表示中)

[トピック内 13 記事 (1 - 13 表示)]  << 0 >>

■65630 / inTopicNo.1)  構造体プロパティをデザイナ自動生成コードでNew宣言させたい
  
□投稿者/ ものくろ (1回)-(2013/03/12(Tue) 20:38:35)

分類:[.NET 全般] 

2013/03/12(Tue) 22:36:46 編集(投稿者)

はじめて利用させていただきます。
VB初心者です。

現在Visual Basic 2010 Express と .NET Framework 2.0で
Windowsアプリケーションを作成しています。
そこで利用するカスタムコントロールを作成中なのですが、
デザイナで自動生成された宣言がエラーとなり困っています。

ExpandableObjectConverterを継承した独自のConverterを作り、
Structureのプロパティが以下の状況になるまでは、実装できました。

1)デザイナ上で展開が可能
+ KobetuBorder
L Left
L Top
L Right
L Bottom

2)デザイナ上での、プロパティの順番(ソート)を指定。
 「Bottom,Left,Right,Top」⇒「Left,Top,Right,Bottom」

3)デザイナ上で、構造体内のプロパティに設定した値を親プロパティにカンマ区切りで表示&その逆。
+ KobetuBorder False,True,False,True
L Left False
L Top True
L Right False
L Bottom True

このプロパティをデザイナ上で設定変更すると、自動生成されるコードに
Me.Label1.KobetuBorder.Left = False
Me.Label1.KobetuBorder.Top = True
Me.Label1.KobetuBorder.Right = False
Me.Label1.KobetuBorder.Bottom= True
と宣言されてしまい、エラーとなってしまいます。

Point、Size、PaddingプロパティのようにNewで宣言されるようにするには、
どうすれば良いのでしょうか?
実際、以下のように宣言されることを望んでいます。
Me.Label1.KobetuBorder = New KobetuBorder(False,True,False,True)

以上です。よろしくお願い致します。

>>追記
実際のソースは↓こんな感じです。

Private _KobetuBorder As New KobetuBorder(False, False, False, False)
<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
Public Property KobetuBorder() As KobetuBorder
Get
Return _KobetuBorder
End Get
Set(ByVal value As KobetuBorder)
_KobetuBorder = value
End Set
End Property

<Serializable()> _
<TypeConverter(GetType(KobetuBorderConverter))> _
Public Structure KobetuBorder

Public Sub New(ByVal left As Boolean , ByVal top As Boolean , ByVal right As Boolean , ByVal bottom As Boolean)
Me.Left = left
Me.Top = top
Me.Right = right
Me.Bottom = bottom
End Sub

Private _Left As Boolean
Private _Top As Boolean
Private _Right As Boolean
Private _Bottom As Boolean

Public Property Left() As Boolean
Get
Return _Left
End Get
Set(ByVal value As Boolean)
_Left = value
End Set
End Property

'----------以下同様のProperty宣言省略----------

End Structure

Public Class KobetuBorderConverter
Inherits ExpandableObjectConverter

Public Overloads Overrides Function CanConvertTo( ByVal context As ITypeDescriptorContext, ByVal destinationType As Type) As Boolean

If destinationType Is GetType(KobetuBorder) Then
Return True
End If
Return MyBase.CanConvertTo(context, destinationType)
End Function

Public Overloads Overrides Function ConvertTo( ByVal context As ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As Type) As Object

If destinationType Is GetType(String) And TypeOf value Is KobetuBorder Then
Dim kBorder As KobetuBorder = CType(value, KobetuBorder)
Return kBorder.Left.ToString() & "," & kBorder.Top.ToString() & "," & kBorder.Right.ToString() & "," & kBorder.Bottom.ToString()
End If
Return MyBase.ConvertTo(context, culture, value, destinationType)
End Function

Public Overloads Overrides Function CanConvertFrom( ByVal context As ITypeDescriptorContext, ByVal sourceType As Type) As Boolean

If sourceType Is GetType(String) Then
Return True
End If
Return MyBase.CanConvertFrom(context, sourceType)
End Function

Public Overloads Overrides Function ConvertFrom(ByVal context As ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object) As Object

If TypeOf value Is String Then
Dim ss As String() = value.ToString().Split(New Char() {","c}, 4)
Dim kBorder As New KobetuBorder(ss(0), ss(1), ss(2), ss(3))
Return kBorder
End If
Return MyBase.ConvertFrom(context, culture, value)
End Function

Public Overrides Function GetCreateInstanceSupported(context As System.ComponentModel.ITypeDescriptorContext) As Boolean

If context.PropertyDescriptor.PropertyType Is GetType(KobetuBorder) Then
Return True
End If
Return MyBase.GetCreateInstanceSupported(context)
End Function

Public Overrides Function CreateInstance(context As System.ComponentModel.ITypeDescriptorContext, propertyValues As System.Collections.IDictionary) As Object

If context.PropertyDescriptor.PropertyType Is GetType(KobetuBorder) Then
Return New KobetuBorder(propertyValues("Left"), propertyValues("Top"), propertyValues("Right"), propertyValues("Bottom"))
End If
Return MyBase.CreateInstance(context, propertyValues)
End Function

Public Overloads Overrides Function GetProperties(context As System.ComponentModel.ITypeDescriptorContext, value As Object, attributes() As System.Attribute) As System.ComponentModel.PropertyDescriptorCollection
'--------- ソート用なので省略
End Function

Public Overloads Overrides Function GetPropertiesSupported(context As System.ComponentModel.ITypeDescriptorContext) As Boolean
'--------- ソート用なので省略
End Function

引用返信 編集キー/
■65632 / inTopicNo.2)  Re[1]: 構造体プロパティをデザイナ自動生成コードでNew宣言させたい
□投稿者/ howling (230回)-(2013/03/12(Tue) 21:26:07)
No65630 (ものくろ さん) に返信
こんばんわ。

VBはちょっとわからないのですが、
C#で似たようなことをやりました。
ConvertFromメソッドは無いでしょうか?
同様にして、CanConvertFromメソッドも。

CanConvertFromメソッドでtrueと返す物は、
そのグリッドに何か書かれた際に、変換が可能であることを示します。まずこれをtrueに。

次に、実際に来る値(おそらくstringかな)を見て、
自分でコンバートしてあげるわけです。これがConvertFrom。
戻り値は、newした…これはRectangleなのかな?です。
この戻り値がおかしい場合もエラーになります。
変換可能って言ったくせにできないじゃん、ってことで。
引用返信 編集キー/
■65634 / inTopicNo.3)  Re[2]: 構造体プロパティをデザイナ自動生成コードでNew宣言させたい
□投稿者/ ものくろ (2回)-(2013/03/12(Tue) 22:22:49)
2013/03/12(Tue) 22:38:31 編集(投稿者)

No65632 (howling さん) に返信

> ConvertFromメソッドは無いでしょうか?
> 同様にして、CanConvertFromメソッドも。
> CanConvertFromメソッドでtrueと返す物は、
> そのグリッドに何か書かれた際に、変換が可能であることを示します。まずこれをtrueに。
> 次に、実際に来る値(おそらくstringかな)を見て、
> 自分でコンバートしてあげるわけです。これがConvertFrom。
> 戻り値は、newした…これはRectangleなのかな?です。
> この戻り値がおかしい場合もエラーになります。
> 変換可能って言ったくせにできないじゃん、ってことで。

howlingさん、回答をありがとうございます。
CanConvertFrom、ConvertFromは実装しています。

実際のソースを最初の記事に追記しました。

※編集箇所
貼りつけたソースを最初の記事に移しました。
引用返信 編集キー/
■65636 / inTopicNo.4)  Re[3]: 構造体プロパティをデザイナ自動生成コードでNew宣言させたい
□投稿者/ howling (231回)-(2013/03/12(Tue) 22:45:16)
うーん、とりあえず勘違いしていた模様。
私の場合はPropertyGridViewでやっていたから、問題がそこだと思ったけれども、
今回はデザイナ上での話でしたね。

デザイナ上でこういったカスタムコントロール追加したことは無いなぁ。
同じクラスなあたり、似たようなものだと思うんだけど。申し訳ないです。
引用返信 編集キー/
■65637 / inTopicNo.5)  Re[4]: 構造体プロパティをデザイナ自動生成コードでNew宣言させたい
□投稿者/ ものくろ (3回)-(2013/03/12(Tue) 22:57:02)
No65636 (howling さん) に返信
> うーん、とりあえず勘違いしていた模様。
> 私の場合はPropertyGridViewでやっていたから、問題がそこだと思ったけれども、
> 今回はデザイナ上での話でしたね。
>
> デザイナ上でこういったカスタムコントロール追加したことは無いなぁ。
> 同じクラスなあたり、似たようなものだと思うんだけど。申し訳ないです。

いえいえ、わざわざ記事を読んで、ご回答くださっただけでも感謝です。
親切にありがとうございました。
引用返信 編集キー/
■65640 / inTopicNo.6)  Re[5]: 構造体プロパティをデザイナ自動生成コードでNew宣言させたい
□投稿者/ Hongliang (41回)-(2013/03/12(Tue) 23:46:15)
試せないですが、DesignerSerializationVisibilityをVisibleにしてやればどうでしょう?
引用返信 編集キー/
■65647 / inTopicNo.7)  Re[6]: 構造体プロパティをデザイナ自動生成コードでNew宣言させたい
□投稿者/ ものくろ (4回)-(2013/03/13(Wed) 11:12:25)
No65640 (Hongliang さん) に返信
> 試せないですが、DesignerSerializationVisibilityをVisibleにしてやればどうでしょう?

Hongliangさん、回答をありがとうございます。
試してみたところ、デザイナファイルに
Me.Label1.KobetuBorder = Ctype(resources.GetObject("Label1.KobetuBorder"), CLib.LabelEx.KobetuBorder)
と記述され、デバッグしようとすると、
String "CLib.LabelEx+KobetuBorder"から型'Boolean'への変換は無効です。
となり、実行できませんでした。

※カスタムコントロールとそれを使う画面は、同じソリューション、別プロジェクトです。
今はプロジェクトを参照していますが、最終的にはdll参照します。
引用返信 編集キー/
■65886 / inTopicNo.8)  Re[7]: 構造体プロパティをデザイナ自動生成コードでNew宣言させたい
□投稿者/ ものくろ (5回)-(2013/03/21(Thu) 20:35:20)
解決しないようなので、クローズします。
Classで宣言する手法に変えてみます。
ありがとうございました。
引用返信 編集キー/
■65890 / inTopicNo.9)  Re[8]: 構造体プロパティをデザイナ自動生成コードでNew宣言させたい
□投稿者/ shu (238回)-(2013/03/21(Thu) 23:08:18)
No65886 (ものくろ さん) に返信
> 解決しないようなので、クローズします。
> Classで宣言する手法に変えてみます。
> ありがとうございました。
解決させるのはものくろ さん自身です。
解決しないのは解決させるための材料を提供しないからではないでしょうか。
引用返信 編集キー/
■65893 / inTopicNo.10)  Re[9]: 構造体プロパティをデザイナ自動生成コードでNew宣言させたい
□投稿者/ Hongliang (48回)-(2013/03/21(Thu) 23:47:14)
> 解決しないのは解決させるための材料を提供しないからではないでしょうか。

うにゃー、この件は十分に材料は出ていたと思います。あとは知識あるいは検索力の問題。

でようやく調べられたのですが、CanConvertTo/ConvertToでInstanceDescriptorへの変換をサポートすれば、newによる代入が行えるようになるようです。
// あ、もちろんDesignerSerializationVisibilityはVisibleで。
InstanceDescriptorで検索すればそのものずばりなコードが見つかります。

なおCanConvertToの結果はVSがキャッシュするみたいなので、CanConvertToをInstanceDescriptorに対応するようにした後、一旦VSを再起動する必要があるかもしれません。
引用返信 編集キー/
■65895 / inTopicNo.11)  Re[10]: 構造体プロパティをデザイナ自動生成コードでNew宣言させたい
□投稿者/ shu (240回)-(2013/03/22(Fri) 07:38:23)
No65893 (Hongliang さん) に返信
>>解決しないのは解決させるための材料を提供しないからではないでしょうか。
>
> うにゃー、この件は十分に材料は出ていたと思います。あとは知識あるいは検索力の問題。
>
『解決しないようなので』という内容に対するコメントなのでこのスレ内でどんなに材料を
出していたとしてもこの結論を出したという事は自分で解決する努力をしてなかったのでは?と
思った次第です。
引用返信 編集キー/
■65900 / inTopicNo.12)  Re[11]: 構造体プロパティをデザイナ自動生成コードでNew宣言させたい
□投稿者/ howling (258回)-(2013/03/22(Fri) 09:50:41)
No65895 (shu さん) に返信
> ■No65893 (Hongliang さん) に返信
> >>解決しないのは解決させるための材料を提供しないからではないでしょうか。
>>
>>うにゃー、この件は十分に材料は出ていたと思います。あとは知識あるいは検索力の問題。
>>
> 『解決しないようなので』という内容に対するコメントなのでこのスレ内でどんなに材料を
> 出していたとしてもこの結論を出したという事は自分で解決する努力をしてなかったのでは?と
> 思った次第です。

この掲示板に書かれる質問に対して答える義務自体は無いですが、
私も答えられるだけの材料自体は揃っていたと思います。
ただ、途中からおそらく別作業に入ったと思うのですが、
提示してもらった回答の方法のみ試す、というサイクルになっていたようですので、
お互いにこれをやってダメだった(try&error)といった内容を書いていければ良かったのかなと思います。

とはいえ、解決できそうですね!結構近い問題に当たっていたので、勉強になります。ありがとうございます!>質問者の方&Hongliangさん
引用返信 編集キー/
■65920 / inTopicNo.13)  Re[12]: 構造体プロパティをデザイナ自動生成コードでNew宣言させたい
□投稿者/ ものくろ (6回)-(2013/03/23(Sat) 01:59:31)
すいません。私の言葉の表現が悪かったです。
他人任せにしてと、不快に思った方にはお詫び致します。

実際は、クローズコメントをする少し前まで実装方法を調べていました。
その中で、「InstanceDescriptor」も試してみたのですが、上手く動作しませんでした。
その為、私自身が調査した結果も進展していないという認識で、状況を記載しませんでした。
記事も後ろに流れ、私自身が解決策を提示する見通しもたたず、このまま放置(に見える)状態なのも問題かと思い、
あのようなコメントを残しました。

現在は手法を妥協して、クラス宣言と親クラスを渡す手法で実現しています。
色々アドバイスをしてくださり、ありがとうございました。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -