アクティブコントロール名を取得するには?

解決


唯香  2008-07-08 14:10:29  No: 140039  IP: 192.*.*.*

いつも参考にさせていただいております。

.Net初心者です。
vb6のプログラムを現在vb2008に修正しております。

フォームにはSplitContainerを貼り付け
Panel2にテキストボックス(txtCD)を配置しています。

txtCD_TextChangedイベントで
実際に入力したときに実行する処理と
プログラムからデータが変更された場合の処理を分けています。

この判断をvb6では以下のように判断しました。
IF txtCD.Parent.ActiveControl.Name = txtCD.Name Then

vb2008では以下のように記述しましたが
SplitContainerの名前が戻ってきます。
IF txtCD.FindForm.ActiveControl.Name = txtCD.Name Then

調べてみるとこちら↓のサイト様のコメントに
http://blogs.wankuma.com/naoko/archive/2007/03/30/69542.aspx
「SplitContainer を使うと Form.ActiveControl がちょっと期待ハズレになってしまう点にお気をつけあれ。」とありました。
まさしくその現象が起こっていると思われるのですが

SplitContainerを外さない限り欲しい結果は得られないのでしょうか?


[vb2008/xp(sp3)]

編集 削除
matsu  2008-07-08 17:55:06  No: 140040  IP: 192.*.*.*

>txtCD_TextChangedイベントで
>実際に入力したときに実行する処理と
>プログラムからデータが変更された場合の処理を分けています。
>
>この判断をvb6では以下のように判断しました。
>IF txtCD.Parent.ActiveControl.Name = txtCD.Name Then
>
>vb2008では以下のように記述しましたが
>SplitContainerの名前が戻ってきます。
>IF txtCD.FindForm.ActiveControl.Name = txtCD.Name Then

ActiveControl.Nameではなく、txtCD.Focusedでフォーカスを持っているか
では判断できませんか?

編集 削除
我龍院  2008-07-08 19:17:38  No: 140041  IP: 192.*.*.*

Dim StringActveControl As String = Me.ActiveControl.GetType.ToString()
        If StringActveControl = "System.Windows.Forms.SplitContainer" Then
            If (SplitContainer1.ActiveControl IsNot Nothing) Then
                StringActveControl = SplitContainer1.ActiveControl.Name.ToString()
            End If
        End If
        If StringActveControl = txtCD.Name Then
            'MessageBox.Show(StringActveControl)
        End If
こんなかな。

編集 削除
我龍院  2008-07-08 19:26:04  No: 140042  IP: 192.*.*.*

あれ!もっと簡単になりそうだな。
あとはご自分でごにょごにょやってください。

編集 削除
我龍院  2008-07-09 07:57:58  No: 140043  IP: 192.*.*.*

If SplitContainer1.ActiveControl IsNot Nothing AndAlso _
            DirectCast(SplitContainer1.ActiveControl, TextBox) Is txtCD Then
            'Do Something
        End If
なんとなく後味が悪いので結局書いてしまった。
        If DirectCast(SplitContainer1.ActiveControl, TextBox) Is txtCD Then
            'Do Something
        End If
でも良さそうだが、なんかのタイミングで例の
「オブジェクト参照がオブジェクト インスタンスに設定されていません。」
と言うのが出る可能性あり。

編集 削除
唯香  2008-07-09 11:42:48  No: 140044  IP: 192.*.*.*

matsuさん 我龍院さん
お返事ありがとうございます。

matsuさんに教えていただいたFocusedで
フォーカスを持っているかが判断できました。
vb6にはない便利なプロパティですね。
ActiveControlにこだわって検索していたせいで
1日中SplitContainerを外すか悩んでいました。

我龍院さんのソースはとても参考になりました。
何度もお返事をいただき今日も早朝から
気にかけてくださったようで本当に感謝しております。
SplitContainerにもActiveControlがあることを知らず
このように判断できることを学びました。


matsuさん 我龍院さん
本当にありがとうございました!

編集 削除
魔界の仮面弁士  2008-07-09 13:01:04  No: 140045  IP: 192.*.*.*

DirectCast してはマズイと思いますよ。>我龍院さん

編集 削除
我龍院  2008-07-09 15:01:03  No: 140046  IP: 192.*.*.*

魔界の仮面弁士さん
ご指摘のとおり確かにマズイ、SplitContainerに何が乗ってるかわかりませんからね。 
        If SplitContainer1.ActiveControl IsNot Nothing AndAlso _
            TypeOf SplitContainer1.ActiveControl Is TextBox AndAlso _
            DirectCast(SplitContainer1.ActiveControl, TextBox) Is txtCD Then
            'Do Something
        End If
かな。
読みやすくするんだったら
        Dim obj As Object = SplitContainer1.ActiveControl
        If obj IsNot Nothing AndAlso _
            TypeOf obj Is TextBox AndAlso _
             DirectCast(obj, TextBox) Is txtCD Then
            'Do Something
        End If

最初に書いたように名前でやるとキャストはいらないが,いまいち.....
        If SplitContainer1.ActiveControl IsNot Nothing AndAlso _
            SplitContainer1.ActiveControl.Name = txtCD.Name Then
             'Do Something
        End If

面倒なので邪道だけど
        Try
            If SplitContainer1.ActiveControl Is txtCD Then
                 'Do Something
            End If
        Catch ex As Exception
        End Try

編集 削除
魔界の仮面弁士  2008-07-09 18:15:07  No: 140047  IP: 192.*.*.*

> 面倒なので邪道だけど

その最後のパターンである
  「If SplitContainer1.ActiveControl Is txtCD Then」
が、Catch 句に入る場合というのは、具体的には
どのような状況において、何の Exception を想定しているのでしょうか?

編集 削除
我龍院  2008-07-09 19:34:02  No: 140048  IP: 192.*.*.*

>何の Exception を想定しているのでしょうか?
その辺を考えるのが面倒と言うことで、どんな例外が
出るか考えないで書くのを邪道と.....

Nothingの時はどうかと漠然と考えたのですが、その時は
例外は発生しないか。

編集 削除