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

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

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

カスタムコントロールのデフォルト値を設定するには?

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

■90167 / inTopicNo.1)  カスタムコントロールのデフォルト値を設定するには?
  
□投稿者/ じきじき (1回)-(2019/02/13(Wed) 19:40:06)

分類:[.NET 全般] 

カスタムコントロールを新規作成した時に
最初に設定されるデフォルト値を設定したいのですが、
どうしたら良いですか?

Inheritsで既存のコントロールを使ったとしての
既存ではないプロパティの場合には

Public Property Min2() As Single = 8

のようにして設定できますが
既存のプロパティの場合にはどのようにすれば設定できますでしょうか?

https://jehupc.exblog.jp/7738993/

このページのように
Public Sub New()
に記述すると、
既に生成してあるコントロールの値まで書き換わってしまいます。




引用返信 編集キー/
■90168 / inTopicNo.2)  Re[1]: カスタムコントロールのデフォルト値を設定するには?
□投稿者/ 魔界の仮面弁士 (2050回)-(2019/02/13(Wed) 21:09:56)
No90167 (じきじき さん) に返信
> デフォルト値を設定したい
> Public Property Min2() As Single = 8

それは Default Value (既定値) ではなく、Initial Value (既定値) ですね。


既定値を指定するのであれば、

'Imports System.ComponentModel
<DefaultValue(8F)> _
Public Property Min2() As Single = 8F

のようにします。

もしも DefaultValueAttribute では取り扱えないようなデータの場合には、
既定値を取り扱うために、ShouldSerializeX と ResetX メソッドを設けます。
(DefaultValueAttribute との併用は NG)

Private Function ShouldSerializeMin2() As Boolean
Private Sub ResetMin2()



また、デザイナー画面から使うことを想定したものの場合には、
Min2 プロパティが変更されたことを通知できるよう、自動実装プロパティにはせず、
通常のプロパティ実装にして、その中で Min2Changed イベントを RaiseEvent した方が望ましいケースもあります。


> 既存のプロパティの場合にはどのようにすれば設定できますでしょうか?

「すでに生成してあるコントロールの値」の意味が分かりませんが、
継承したコントロール自身のコンストラクタでは駄目なのでしょうか。


追加したプロパティではなく、継承元クラスが持つプロパティの場合、
元のプロパティが Overridable な場合は、Overrides して振る舞いを変えます。

Overridable でない場合は、振る舞いを変えるための直接的な方法は無いので、
BrowsableAttribute で元のプロパティを隠して、代わりに別のプロパティ名を付与する方法もあります。
(Shadows でお茶を濁す手もありますが、これだと基底メンバーの上書きにはならないので)
引用返信 編集キー/
■90170 / inTopicNo.3)  Re[2]: カスタムコントロールのデフォルト値を設定するには?
□投稿者/ じきじき (2回)-(2019/02/13(Wed) 21:55:52)
ありがとうございます。

例えば、
テキストボックスを継承したカスタムコントロールを作ったとして
そのフォントの規定値をArialに変えたい場合には
どのようにしたら良いですか?


既に生成してあるコントロールとは、
あるカスタムコントロールを作成したとします。
そしてフォームにそのコントロールを追加します。
その後で、そのカスタムコントロールのコードで規定値設定を書き換えたとして
先ほど生成したコントロールに影響を及ぼさないようにしたいのですが・・・
引用返信 編集キー/
■90171 / inTopicNo.4)  Re[1]: カスタムコントロールのデフォルト値を設定するには?
□投稿者/ 魔界の仮面弁士 (2051回)-(2019/02/13(Wed) 21:59:56)
No90167 (じきじき さん) に返信
> カスタムコントロールを新規作成した時に
> 最初に設定されるデフォルト値を設定したいのですが、
> どうしたら良いですか?

上記がデザイナー依存の話と仮定して、カスタムコントロールの Text プロパティに、
「フォーム名.コントロール名」を初期値として与えてみる例。


<System.ComponentModel.Designer(GetType(CustomControl.CustomControlDesigner))>
Partial Public Class CustomControl
 Inherits System.Windows.Forms.Control

 Public Sub New()
  InitializeComponent()
 End Sub

 Protected Overrides Sub OnPaint(e As PaintEventArgs)
  MyBase.OnPaint(e)
  e.Graphics.DrawString(Me.Text, Me.Font, Brushes.Black, PointF.Empty)
 End Sub

 Protected Overrides Sub OnControlAdded(e As ControlEventArgs)
  MyBase.OnControlAdded(e)
 End Sub

 Friend Class CustomControlDesigner
  Inherits System.Windows.Forms.Design.ControlDesigner
  Public Overrides Sub InitializeNewComponent(ByVal defaultValues As System.Collections.IDictionary)
   MyBase.InitializeNewComponent(defaultValues)
   Dim f As Form = Me.Control.FindForm()
   If f IsNot Nothing Then
    Me.Control.Text = f.Name & "." & Me.Control.Name
   Else
    Me.Control.Text = Me.Control.Name
   End If
  End Sub
 End Class
End Class
引用返信 編集キー/
■90172 / inTopicNo.5)  Re[3]: カスタムコントロールのデフォルト値を設定するには?
□投稿者/ 魔界の仮面弁士 (2052回)-(2019/02/13(Wed) 22:08:19)
No90170 (じきじき さん) に返信
> テキストボックスを継承したカスタムコントロールを作ったとして
> そのフォントの規定値をArialに変えたい場合には
> どのようにしたら良いですか?

既存の Form1.designer.vb 内を確認してみてください。

そこに、
 Me.YourControl1.CustomFont = New System.Drawing.Font(……)
のようなフォント設定が記載されているかどうかが、まず起点となります。

上記の行が無い場合、シリアライズの必要のない「既定値」が使われていたものと判断されます。
(Font プロパティや BackColor プロパティ等のように、アンビエントなプロパティは特に注意)

指定があった場合は、普通にインスタンス化した後でプロパティが指定されるだけなので、
特に問題は無いでしょう。
指定が無い場合は、作成したコントロール側の最初の振る舞いに依存します。


Form1.designer.vb 内にシリアライズされているフォント設定が、そもそも想定と異なるなら、
カスタムコントロールそのものだけでなく、既に配置済みのコントロールの設定値自体が
間違っていたことになるので、デザイン時設定をやりなおす必要があると思います。
引用返信 編集キー/
■90173 / inTopicNo.6)  Re[4]: カスタムコントロールのデフォルト値を設定するには?
□投稿者/ 魔界の仮面弁士 (2053回)-(2019/02/14(Thu) 00:47:21)
No90172 (魔界の仮面弁士) に追記
> 指定があった場合は、普通にインスタンス化した後でプロパティが指定されるだけなので、
> 特に問題は無いでしょう。
> 指定が無い場合は、作成したコントロール側の最初の振る舞いに依存します。


たとえば、こんな感じのフォームがあるとします。
System.Windows.Forms.GroupBox が 2 つと
System.Windows.Forms.TextBox が 4 つあるフォームです。


 Form1 (Font 既定値 … MS UI Gothic, 9pt)
 ├GroupBox1 (Font 未設定)
 │├TextBoxA1 (Font 未設定)
 │└TextBoxB1 ("MS ゴシック, 20pt")
 └GroupBox2 ("MS UI Gothic, 20pt")
  ├TextBoxA2 (Font 未設定)
  └TextBoxB2 ("MS ゴシック, 20pt")


上記フォームの作成手順としては、まず GroupBox1 と GroupBox2 を Form1 に貼り、
GroupBox1 の Font は未設定(MS UI Gothic, 9pt)、
GroupBox2 の Font は "MS UI Gothic, 20pt" にします。

GroupBox1 の上に 2 つのテキストボックス TextBoxA1 と TextBoxB1 を貼り、
GroupBox2 の上に 2 つのテキストボックス TextBoxA2 と TextBoxB2 を貼ります。

TextBoxA1 と TextBoxA2 の Font は未設定、
TextBoxB1 と TextBoxB2 の Font は "MS ゴシック, 20pt" とした状態です。これで準備完了。



この時、Form1 のデザイン時画面で各テキストボックスのプロパティグリッドを見ると、
TextBoxB1 / TextBoxB2 の Font プロパティの行は太字で表記されていますが、
TextBoxA1 / TextBoxA2 の Font プロパティの行は未設定なので、太字表現になっていないはず。


そもそも Font プロパティはアンビエントである物なので、基本的には
親コントロールの Font を受け継ぐことになっています。
そのため、TextBoxA1 と TextBoxA2 の Font の値は、
どちらも未設定ではありますが、両者が示す値は異なっており、
TextBoxA1 は "MS UI Gothic, 9pt" で、
TextBoxA2 は "MS UI Gothic, 20pt" として扱われます。


―――という点を踏まえた上で。


もしもテキストボックスを継承して、画面に貼った直後に
Font が "Arial, 12pt" に設定されるようにしたいとしましょう。

その場合、新規にコントロールを貼る場合は良いとして、
既存の上記フォーム画面を開いた場合、各 Font の振る舞いはどうあるべきかを
考える必要があると思います。

TextBoxB1, TextBoxB2 の Font は、設定された通り "MS ゴシック, 20pt" のままで良いとして、
問題は Font 未設定である TextBoxA1 と TextBoxA2 の扱い。


Form1.designer.vb 上で Font プロパティがシリアライズされていない以上、
Font 設定済み(プロパティグリッド上で太字表現)の状態にはなりえないはず。


となると、「未設定時は "Arial, 12pt" とみなす」ようにするか、
「未設定時は従来通り、親 Font を受け継ぐ」実装にするのかの二択では無いでしょうか。
(試していませんけれども)


未設定時の既定値を割り当てる方法については、 No90168 で述べた通りですし、
InitializeComponent からシリアライズされた値を受け取るタイミングで対処したいなら
No90171 でも用いたデザイナクラスで処置できるんじゃないかな…? (自信無し)

http://systemartlaboratory.com/netdefaultvalue.html
引用返信 編集キー/

このトピックをツリーで一括表示


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

このトピックに書きこむ