none
フォームの起動時に、MenuItemが押下されたボタン表示になってしまいます。 RRS feed

  • 質問

  • FormとWPFの相互運用についていろいろと試しています。
    ElementHostを使って、メニューをWPFのMenuにしてみたところ、フォームの起動時に、Menuの最初のMenuItemが押下されたボタン表示になってしまいます。実害は無さそうですが、見た目が悪いです。

    再現手順
    1.Windows フォームプロジェクトを新規作成する。(WindowsFormApplication1)
    2.ソリューションエクスプローラーにて、WindowsFormApplication1を右クリックし、追加を選び、ユーザーコントロール(xamlの方)を選び、名前をWpfMenu.xamlとして追加する。WpfMenu.xamlを以下のように変更する。

    <UserControl x:Class="WindowsFormApplication1.WpfMenu"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <Menu Name="wpfMenu" Height="24">
            <MenuItem Header="_File">
                <MenuItem Header="_Close" Name="menuItemCloseC"/>
            </MenuItem>
            <MenuItem Header="_Test"/>
        </Menu>
    </UserControl>
    

    3.Form1のデザイナに移り、ツールボックスからWPF 相互運用機能のElementHostを選び、Form1のクライアント領域に貼り付け、プロパティタブでHeight=24、Dock=Topに設定。(elementHost1)
    4.F6を押してビルドし、elementHost1の右上の小さな三角ボタンを押し、ホストするコンテンツの選択でwpfMenu1を選ぶ。
    5.F5を押す。→WindowsFormApplication1が起動し、「File」が押下したボタン表示になっている。

    当方の環境
    Vista Ultimate SP2
    Visual C# 2010 Express SP1
    .NET Framework 4.0

    Formではなく、Windowに同様のメニューを用意すれば、当然ながら押下表示にはなりません。
    FormでWPFのMenuを使い、起動時に、押下していないボタンにするには、どうしたらよいでしょうか。

    2012年3月5日 8:51

すべての返信

  • たぶん、WindowsFormの起動時にelementHost1がフォーカスを持っているので、WpfMenuで最初のエレメントであるMenuである「File」にフォーカスがあたったままになってるんだと思います。

    つまり、起動時にelementHost1にフォーカスがなければいいのです。
    簡単な手段なら、Form1内のTABオーダーが0になるコントロールを他に用意してやれば、そちらに起動時のフォーカスが移るので、押された状態では起動しないはずですよ。


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答の候補に設定 山本春海 2012年3月28日 6:46
    2012年3月5日 11:47
  • gekkaさん

    コメント、ありがとうございます。

    ウィンドウのクライアント領域をクリックすると、押された状態ではなくなるため、フォーカスが原因と言う可能性は私も考えました。そこで、Form1_Lord()にて、Form1.Focus();としてみましたが、ダメでした。一方、「Test」にNameを付けてからmenuItemTestT.Focus();とすると、「Test」が押下状態となりました。

    また、gekkaさんの提案通り、ボタンをクライアント領域に貼り付けて、TabIndex=0とし、elementHost1の方はTabIndex=1とすると、起動時にボタンにフォーカスがあたり、「File」の押下は無くなりました。

    ただ、できれば余分なコントロールは追加したくはありません。そう思って、PanelをelementHost1の下に敷いて、TabIndex=0としてみましたが、効果はありませんでした。

    しかたがないので、サイズが(0,0)のボタンをクライアント領域の隅に配置し、TabIndex=0とすると、期待した結果が得られました。

    以上のようにいろいろ試してみて、elementHost1がTabIndex=0のため、起動時にフォーカスがあたって押下状態になるというのは分かったような気がします。でも、なんかちょっとスッキリしません。^^;

    というのも、だったら、どうしてFormのMenuStripやWPFのWindowにおけるMenuだと、起動時にフォーカスがあたって押下状態にならないのでしょうか? ならない理由を今回の事例に適用できればと思うのですが。

    2012年3月5日 17:22
  • というのも、だったら、どうしてFormのMenuStripやWPFのWindowにおけるMenuだと、起動時にフォーカスがあたって押下状態にならないのでしょうか? ならない理由を今回の事例に適用できればと思うのですが。

    WindowsFormsのMenuStripでもTabStopをTrueにしてやると、押された状態で起動できます。
    逆にElementHostのTagStopをFalseにする方法でもWPFのMenuにフォーカスがいかなくなります。(アクセラレータが消えてたりしますが...)

    #WPFオンリーでフォーカス与える方法は調べきれてません


    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2012年3月5日 23:36
  • gekkaさんのおっしゃる通り、elementHost1のTabStopをFalseにすると、起動時に押されていない状態となりますね。素晴らしい! で、これまたgekkaさんご指摘の通り、Altを押しても最初はアクセラレータの下線が出ませんね。

    FormのMainMenuStrip、MenuのIsMainMenu周辺がクサイと思うのですが、どう対処して良いやら。。。

    WPFはMDIをサポートしないので、MDIが必要ならFormとの相互運用機能を使うようにとエッセンシャルWPFに書いてあったのですが、アプリの玄関たるメニューが格好良くできないというのは、困りました。

    2012年3月6日 21:04