none
サブメニューのAutomationElementが取得できない RRS feed

  • 質問

  • Visual Studio 2013、WPFアプリケーションをUIAutomationを使用してテストしようとしています。

    [メニュー]

    ファイル

    └開く

    ①ウィンドウからMenuのAutomationElementを取得

    ②①からMenuItem(ファイル)のAutomationElementを取得

    ③②からMenuItem(開く)のAutomationElementを取得   ← ここが取得できません。

    FindFirst、FindAll、TreeWalker、CachedChildrenなど色々試してみたのですが、nullやcountが0になります。

    サブメニューを取得し実行するにはどうすれば良いでしょうか?

    2015年9月15日 13:10

回答

  • こんな?

    <Window x:Class="WpfApplication5.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Grid VerticalAlignment="Top">
                <Menu>
                    <MenuItem Header="File" AutomationProperties.AutomationId="F">
                        <MenuItem Header="開く" AutomationProperties.AutomationId="O">
                            <MenuItem Header="File1"  AutomationProperties.AutomationId="1"
                                      Click="MenuItem_Click"/>
                        </MenuItem>
                        <MenuItem Header="終了" AutomationProperties.AutomationId="X"/>
                    </MenuItem>
                </Menu>
            </Grid>
    
            <Button Width="100" Height="100" Content="Test" Click="Button_Click"/>
        </Grid>
    </Window>
    using System.Linq;
    using System.Windows;
    using System.Windows.Automation;//UIAutomationClient , UIAutomationTypes
    namespace WpfApplication5
    {
    
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                var hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
    
                var menuItemCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.MenuItem);
                var menuFileCondition = new PropertyCondition(AutomationElement.AutomationIdProperty, "F");
    
                var ae = AutomationElement.FromHandle(hwnd);
                var menuFile = ae.FindFirst(TreeScope.Subtree, new AndCondition(menuItemCondition, menuFileCondition));
                if (menuFile == null)
                {
                    return;
                }
    
                //展開機能がサポートされているか
                if (!menuFile.GetSupportedPatterns().Contains(ExpandCollapsePattern.Pattern))
                {
                    return;
                }
                //展開機能をとりだし
                var exp = (ExpandCollapsePattern)menuFile.GetCurrentPattern(ExpandCollapsePattern.Pattern);
                if (exp != null)
                {
                    //展開させる
                    exp.Expand();
    
                    //展開させてから子要素を探す
                    var subItems = menuFile.FindAll(TreeScope.Children | TreeScope.Descendants, menuItemCondition);
                    foreach (AutomationElement sub in subItems)
                    {
                        string name = sub.Current.Name;
                        string id = sub.Current.AutomationId;
                        System.Diagnostics.Debug.WriteLine(id+"\t"+name);
                    }
    
                    var menuOpen=menuFile.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "O"));
                    var exp2=(ExpandCollapsePattern)menuOpen.GetCurrentPattern(ExpandCollapsePattern.Pattern);
                    if (exp2 != null)
                    {
                        exp2.Expand();
    
                        var menuFile1 = menuOpen.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "1"));
                        if (menuFile1 != null)
                        {
                            var x=(InvokePattern) menuFile1.GetCurrentPattern(InvokePattern.Pattern);
                            x.Invoke();
                        }
                    }
                }
            }
    
            private void MenuItem_Click(object sender, RoutedEventArgs e)
            {
                MessageBox.Show("OK");
            }
        }
    }



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

    • 回答の候補に設定 星 睦美 2015年9月16日 1:50
    • 回答としてマーク 星 睦美 2015年10月8日 5:42
    2015年9月15日 14:54

すべての返信

  • こんな?

    <Window x:Class="WpfApplication5.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Grid VerticalAlignment="Top">
                <Menu>
                    <MenuItem Header="File" AutomationProperties.AutomationId="F">
                        <MenuItem Header="開く" AutomationProperties.AutomationId="O">
                            <MenuItem Header="File1"  AutomationProperties.AutomationId="1"
                                      Click="MenuItem_Click"/>
                        </MenuItem>
                        <MenuItem Header="終了" AutomationProperties.AutomationId="X"/>
                    </MenuItem>
                </Menu>
            </Grid>
    
            <Button Width="100" Height="100" Content="Test" Click="Button_Click"/>
        </Grid>
    </Window>
    using System.Linq;
    using System.Windows;
    using System.Windows.Automation;//UIAutomationClient , UIAutomationTypes
    namespace WpfApplication5
    {
    
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                var hwnd = new System.Windows.Interop.WindowInteropHelper(this).Handle;
    
                var menuItemCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.MenuItem);
                var menuFileCondition = new PropertyCondition(AutomationElement.AutomationIdProperty, "F");
    
                var ae = AutomationElement.FromHandle(hwnd);
                var menuFile = ae.FindFirst(TreeScope.Subtree, new AndCondition(menuItemCondition, menuFileCondition));
                if (menuFile == null)
                {
                    return;
                }
    
                //展開機能がサポートされているか
                if (!menuFile.GetSupportedPatterns().Contains(ExpandCollapsePattern.Pattern))
                {
                    return;
                }
                //展開機能をとりだし
                var exp = (ExpandCollapsePattern)menuFile.GetCurrentPattern(ExpandCollapsePattern.Pattern);
                if (exp != null)
                {
                    //展開させる
                    exp.Expand();
    
                    //展開させてから子要素を探す
                    var subItems = menuFile.FindAll(TreeScope.Children | TreeScope.Descendants, menuItemCondition);
                    foreach (AutomationElement sub in subItems)
                    {
                        string name = sub.Current.Name;
                        string id = sub.Current.AutomationId;
                        System.Diagnostics.Debug.WriteLine(id+"\t"+name);
                    }
    
                    var menuOpen=menuFile.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "O"));
                    var exp2=(ExpandCollapsePattern)menuOpen.GetCurrentPattern(ExpandCollapsePattern.Pattern);
                    if (exp2 != null)
                    {
                        exp2.Expand();
    
                        var menuFile1 = menuOpen.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "1"));
                        if (menuFile1 != null)
                        {
                            var x=(InvokePattern) menuFile1.GetCurrentPattern(InvokePattern.Pattern);
                            x.Invoke();
                        }
                    }
                }
            }
    
            private void MenuItem_Click(object sender, RoutedEventArgs e)
            {
                MessageBox.Show("OK");
            }
        }
    }



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

    • 回答の候補に設定 星 睦美 2015年9月16日 1:50
    • 回答としてマーク 星 睦美 2015年10月8日 5:42
    2015年9月15日 14:54
  • フォーラム オペレーターの星 睦美です。fuchico さん、投稿ありがとうございます。

    fuchico さんからの質問にgekka さんが回答していますので、内容を確認して返信いただければと思います。
    フォーラム ユーザーからの回答がお役にたちましたら、投稿者から[回答としてマーク] をお願いします。

    ・フォーラムのヘルプ


    フォーラム オペレーター 星 睦美 - MSDN Community Support

    2015年9月18日 7:29