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

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

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

Re[2]: 継承元フォームのコントロールについて


(過去ログ 109 を表示中)

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

■64735 / inTopicNo.1)  継承元フォームのコントロールについて
  
□投稿者/ ドミンゲス (1回)-(2012/12/25(Tue) 17:20:30)

分類:[VB.NET/VB2005 以降] 

開発環境:VS2008、.Net Framework3.5.1

Panelを継承し3つのボタンを持つコントロールを作成しました。
各ボタンはPrivateで作成しVisibleのみプロパティとして公開しています。
直接配置したフォームでは動作するのですが、コントロールをProtectedで配置し、
フォームを継承した場合に継承先のフォームで一部のボタンをデザイナで非表示にしても表示されてしまいます。
逆に継承元フォームで非表示にしたボタンを継承先で表示する事は出来ました。

継承先のデザイナを確認してみたところ公開したプロパティがFalseの場合は細字になっていて
DefaultValueがFalseで設定されているためデザイナに書き込まれないのではないかと思い。
ShouldSerializeButtonAVisibleを実装し常にTrueを返すようにしてみたのですが結果は同じでした。

こういった継承元のコントロールを継承先で変更するようなことは出来ないのしょうか?

<コントロールソース>

Public Class CustomPanel
Inherits Panel

Private WithEvents buttonA As Button
Private WithEvents buttonB As Button
Private WithEvents buttonC As Button

Public Sub New()

buttonA = New Button
buttonA.Text = "ボタンA"
buttonA.Size = New Size(100, 25)
buttonA.Left = 3
Me.Controls.Add(buttonA)

buttonB = New Button
buttonB.Text = "ボタンB"
buttonB.Size = New Size(100, 25)
buttonB.Left = buttonA.Left + buttonA.Width + 6
Me.Controls.Add(buttonB)

buttonC = New Button
buttonC.Text = "ボタンC"
buttonC.Size = New Size(100, 25)
buttonC.Left = buttonB.Left + buttonB.Width + 6
Me.Controls.Add(buttonC)

Me.ButtonAVisible = True
Me.ButtonBVisible = True
Me.ButtonCVisible = True

End Sub

Public Property ButtonAVisible() As Boolean
Get
Return buttonA.Visible
End Get
Set(ByVal value As Boolean)
If buttonA.Visible <> value Then
buttonA.Visible = value
End If
End Set
End Property
Public Property ButtonBVisible() As Boolean
Get
Return buttonB.Visible
End Get
Set(ByVal value As Boolean)
If buttonB.Visible <> value Then
buttonB.Visible = value
End If
End Set
End Property
Public Property ButtonCVisible() As Boolean
Get
Return buttonC.Visible
End Get
Set(ByVal value As Boolean)
If buttonC.Visible <> value Then
buttonC.Visible = value
End If
End Set
End Property

Protected Overrides Sub Dispose(ByVal disposing As Boolean)
MyBase.Dispose(disposing)

If Me.buttonA IsNot Nothing Then
Me.buttonA.Dispose()
Me.buttonA = Nothing
End If

If Me.buttonB IsNot Nothing Then
Me.buttonB.Dispose()
Me.buttonB = Nothing
End If

If Me.buttonC IsNot Nothing Then
Me.buttonC.Dispose()
Me.buttonC = Nothing
End If

End Sub

End Class

引用返信 編集キー/
■64736 / inTopicNo.2)  Re[1]: 継承元フォームのコントロールについて
□投稿者/ shu (133回)-(2012/12/25(Tue) 17:42:14)
2012/12/25(Tue) 17:48:54 編集(投稿者)
No64735 (ドミンゲス さん) に返信

>     Public Property ButtonAVisible() As Boolean
>         Get
>             Return buttonA.Visible
>         End Get
>         Set(ByVal value As Boolean)
>             If buttonA.Visible <> value Then
>                 buttonA.Visible = value
>             End If
>         End Set
>     End Property
ここでbuttonA.Visibleを使っているのが駄目です。特に条件判定。


Public Class Form1
    Public Sub New()
        ' この呼び出しはデザイナーで必要です。
        InitializeComponent()

        ' InitializeComponent() 呼び出しの後で初期化を追加します。
        Button1.Visible = True
        Console.WriteLine("New での Button1.Visible = {0}", Button1.Visible)
    End Sub

    Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        Console.WriteLine("Form1_Load での Button1.Visible = {0}(設定前)", Button1.Visible)
        Button1.Visible = True
        Console.WriteLine("Form1_Load での Button1.Visible = {0}(設定後)", Button1.Visible)
    End Sub
End Class

このようなプログラムを実行してみて下さい。
そうするとNewでの Button1.Visible はFalseとなるのが分かると思います。
Load前にVisibleを評価すると実際の設定状況に関わらずFalseとなってしまいます。


なので
If buttonA.Visible <> value Then
では
If False <> value Then
と同じことになるのでvalueがtrueでないと状態が変わらないことになってしまいます。

条件判定をいれたいのならPrivate変数などで別途状態を保持するようにした方がよいと思います。


本題と関係ないですが、こういうコントロールを作るときはUserControlにした方がデザインも
出来るので楽です。

引用返信 編集キー/
■64737 / inTopicNo.3)  Re[2]: 継承元フォームのコントロールについて
□投稿者/ ドミンゲス (2回)-(2012/12/25(Tue) 19:21:04)
No64736 (shu さん) に返信
> 2012/12/25(Tue) 17:48:54 編集(投稿者)
>
> ■No64735 (ドミンゲス さん) に返信
>
>> Public Property ButtonAVisible() As Boolean
>> Get
>> Return buttonA.Visible
>> End Get
>> Set(ByVal value As Boolean)
>> If buttonA.Visible <> value Then
>> buttonA.Visible = value
>> End If
>> End Set
>> End Property
> ここでbuttonA.Visibleを使っているのが駄目です。特に条件判定。
>
>
> Public Class Form1
> Public Sub New()
> ' この呼び出しはデザイナーで必要です。
> InitializeComponent()
>
> ' InitializeComponent() 呼び出しの後で初期化を追加します。
> Button1.Visible = True
> Console.WriteLine("New での Button1.Visible = {0}", Button1.Visible)
> End Sub
>
> Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
> Console.WriteLine("Form1_Load での Button1.Visible = {0}(設定前)", Button1.Visible)
> Button1.Visible = True
> Console.WriteLine("Form1_Load での Button1.Visible = {0}(設定後)", Button1.Visible)
> End Sub
> End Class
>
> このようなプログラムを実行してみて下さい。
> そうするとNewでの Button1.Visible はFalseとなるのが分かると思います。
> Load前にVisibleを評価すると実際の設定状況に関わらずFalseとなってしまいます。
>
>
> なので
> If buttonA.Visible <> value Then
> では
> If False <> value Then
> と同じことになるのでvalueがtrueでないと状態が変わらないことになってしまいます。
>
> 条件判定をいれたいのならPrivate変数などで別途状態を保持するようにした方がよいと思います。
>
>
> 本題と関係ないですが、こういうコントロールを作るときはUserControlにした方がデザインも
> 出来るので楽です。

shu さんご指摘ありがとうございます。

ご指摘頂いた内容を元にPrivate変数に変更しPropertyChangedで処理するように変更し意図した動作が実現できました。
ありがとうございました。

引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -