カスタムコントロールをアクティブにさせないようにするには?

解決


ひば  2007-11-12 17:36:54  No: 144084  IP: 192.*.*.*

カスタムコントロールでボタンのようなものを作成しました。
そのボタンを押してテキストボックスに値を設定します。

条件として、テキストボックスのフォーカス(カーソル)は
維持させたいのですが、カスタムコントロールをクリックすると
カスタムコントロールがアクティブになってしまいます。
(テキストボックスのフォーカスが奪われてしまう)

コントロールがフォーカスを受け取らないように、コンストラクタで
Me.SetStyle(ControlStyles.Selectable, False)
をしてみましたが、かわりません。

どうしたらテキストボックスのフォーカスを奪わずに
カスタムコントロールをクリックできるのでしょうか。

よろしくお願い致します。

編集 削除
魔界の仮面弁士  2007-11-12 18:31:22  No: 144085  IP: 192.*.*.*

> (テキストボックスのフォーカスが奪われてしまう)
当方では再現しませんでした。.NET 2.0 です。

# Visual Studio を立ち上げるのが面倒だったので、メモ帳開発コード…。

'=====
' vbc.exe /t:winexe /out:c:\test.exe c:\test.vb
'-----
Imports System.Windows.Forms
Public Class Form1
  Inherits Form
  Public Shared Sub Main()
    Dim f As New Form1()
    Dim t As New TextBox()
    t.Text = "TextBox"
    f.Controls.Add(t)
    Dim b() As Button = { New Button(), New CustomButton() }
    b(0).Left = t.Right
    b(0).Text = "Button"
    f.Controls.Add(b(0))
    b(1).Left = t.Right
    b(1).Top = b(0).Bottom
    b(1).Text = "CustomButton"
    f.Controls.Add(b(1))
    AddHandler b(0).Click, AddressOf Clicked
    AddHandler b(1).Click, AddressOf Clicked
    Application.Run(f)
  End Sub
  Public Shared Sub Clicked(ByVal s As Object, e As EventArgs)
    MessageBox.Show(DirectCast(s, Button).Text & "が押された。")
  End Sub
End Class

Public Class CustomButton
  Inherits Button
  Public Sub New()
    MyBase.SetStyle(ControlStyles.Selectable, False)
  End Sub
End Class

編集 削除
ひば  2007-11-12 20:07:07  No: 144086  IP: 192.*.*.*

回答ありがとうございます。

環境は、VisualBasic2005です。
カスタムコントロールの「Windowsコントロールライブラリ」と
テスト用の「Windowsアプリケーション」の2つのプロジェクトを
作成しています。

カスタムコントロールはボタンのサブクラスでなく
UserControlです。
テスト用のアプリにカスタムコントロールを貼り付けて
確認しました。

編集 削除
魔界の仮面弁士  2007-11-12 20:55:40  No: 144087  IP: 192.*.*.*

> カスタムコントロールはボタンのサブクラスでなく
> UserControlです。

おぉっ、失礼しました。
ということで、UserControl にしてみましたが…やはり再現せず。


'=====
' vbc.exe /t:winexe /out:c:\test2.exe c:\test2.vb
'-----
Imports System.Windows.Forms
Imports System.Drawing
Public Class Form1
  Inherits Form

  Public Shared Sub Main()
    Application.Run(New Form1())
  End Sub

  Private t As New TextBox()
  Private WithEvents u As New CustomButton()

  Protected overrides Sub OnLoad(e As EventArgs)
    t.Text = "TextBox"
    Controls.Add(t)
    u.Left = t.Right
    u.Size = New Size(100, 40)
    Controls.Add(u)
  End Sub

  Private Sub u_Click(s As Object, e As EventArgs) Handles u.Click
    t.Text = Now().ToString("hh:mm:ss.ffff")
  End Sub
End Class

Public Class CustomButton
  Inherits UserControl
  Public Sub New()
    MyBase.SetStyle(ControlStyles.Selectable, False)
    BackColor = Color.Brown
  End Sub
  Protected overrides Sub OnClick(e As EventArgs)
    Dim r As New Random()
    BackColor = Color.FromArgb(r.Next(0, 256), r.Next(0, 256), r.Next(0, 256))
    MyBase.OnClick(e)
  End Sub
End Class

編集 削除
魔界の仮面弁士  2007-11-12 21:07:52  No: 144088  IP: 192.*.*.*

UserControl 内にボタンを貼ってみましたが、それでもやはり再現しません。
SetStyle(Selectable, False) の呼び出し方が違うのかな…。

現象を再現可能な、最小限のコードを提示していただけませんか?


'=====
' vbc.exe /t:winexe /out:c:\test3.exe c:\test3.vb
'-----
Imports System.Windows.Forms
Imports System.Drawing
Public Class Form1
  Inherits Form

  Public Shared Sub Main()
    Application.Run(New Form1())
  End Sub

  Private t As New TextBox()
  Private WithEvents u As New CustomButton()

  Protected overrides Sub OnLoad(e As EventArgs)
    t.Text = "TextBox"
    Controls.Add(t)
    u.Left = t.Right
    u.Size = New Size(100, 40)
    Controls.Add(u)
  End Sub

  Private Sub u_Click(s As Object, e As EventArgs) Handles u.Click
    t.Text = Now().ToString("hh:mm:ss.ffff")
  End Sub
End Class

Public Class CustomButton
  Inherits UserControl
  Public Sub New()
    MyBase.SetStyle(ControlStyles.Selectable, False)
    Dim b As New InternalButton()
    b.Dock = DockStyle.Fill
    Padding = New Padding(5)
    b.Text = "内部ボタン"
    AddHandler b.Click, AddressOf Clicked
    BackColor = Color.Indigo
    b.BackColor = Color.LightCyan
    Controls.Add(b)
  End Sub
  Private Sub Clicked(s As Object, e As EventArgs)
    MyBase.OnClick(e)
  End Sub
  Protected Overrides Sub OnClick(e As EventArgs)
  End Sub
  Private Class InternalButton
    Inherits Button
    Public Sub New()
      MyBase.SetStyle(ControlStyles.Selectable, False)
    End Sub
  End Class
End Class

編集 削除
魔界の仮面弁士  2007-11-12 21:29:13  No: 144089  IP: 192.*.*.*

あー。我理解。
再現しますね。何か他に手を加えるべき個所があるのかな。

編集 削除
魔界の仮面弁士  2007-11-12 21:44:23  No: 144090  IP: 192.*.*.*

# 連投失礼。m(_ _)m

どうやら、UserControl のベースクラスである「ContainerControl クラス」が、
独自にフォーカス制御を行っているようですね。
http://msdn2.microsoft.com/ja-jp/library/system.windows.forms.containercontrol.aspx


一応、別のクラスに差し替えてやれば、アクティブにならずに済むようです。
  Public Class CustomButton
    'Inherits UserControl
    Inherits Panel
      :
  End Sub

編集 削除
ひば  2007-11-13 10:55:38  No: 144091  IP: 192.*.*.*

もともとフォーカスを受け付けないコントロールを
継承するしかない、ということですね。

デザインは表示できませんが、何とかそれでやってみます。
ありがとうございました。

編集 削除