Help us understand the problem. What is going on with this article?

UIAutomationでDataGridViewCellの値を取ってみるコード[短小コード]

More than 1 year has passed since last update.

目的

  • C#で作られたFormアプリとかを外部操作したい!
  • 今お仕事で課題になってるやつを解決できそうな感じなのでおまとめ。
  • UIAutomationする相手はFormDataGridViewがデーンと置いてあるだけのバカチョンを前提にしています。
  • なんか妙に読める情報1が少ないとこなのでこんなのでも助けになるはず。
  • .NET 4.8から正式に対応するようになったらしいです。コードの内容も変わるのかな?

コード

// このコードを実装したアプリが立ち上がったタイミングでDataGridViewに登録されている値のみ表示できるはず

        /// <param name = "parent"> UIAutomationする対象フォーム</param>
        private List<List<string>> ReadDataGridViewCellValues(AutomationElement parent)
        {
            var rows = new List<List<string>>();

            // Find the DataGridView in question
            // AutomationIDはSPY++とかで調べる感じで
            var datagrid = parent.FindFirst(
                               TreeScope.Descendants, 
                               new PropertyCondition(AutomationElement.AutomationIdProperty, "dataGridView1")); 
            // Find all rows from the DataGridView
            var loginLines = datagrid.FindAll(TreeScope.Descendants, PropertyCondition.TrueCondition);

            foreach (AutomationElement loginLine in loginLines)
            {
                var row = new List<string>();
                var loginLinesDetails = loginLine.FindAll(
                                            TreeScope.Descendants, 
                                            new PropertyCondition(
                                                AutomationElement.ControlTypeProperty,
                                                ControlType.Custom)
                                        );

                for (var i = 0; i < loginLinesDetails.Count; i++)
                {
                    var targetText = loginLinesDetails[i].FindFirst(
                                         TreeScope.Descendants, 
                                         new PropertyCondition(AutomationElement.ClassNameProperty, "TextBlock"));

                    const int automationPropID_dgvCellValue = 30045; // 地道な調査で突き止めたID。環境によって違ったりしたらごめんね。
                    var temp = (string)loginLinesDetails[i].GetCurrentPropertyValue(
                                   AutomationProperty.LookupById(automationPropID_dgvCellValue));
                    // GetCachedPropertyValue()てのもあって、気にはなるけどそっちを使うとInvalidOperationExceptionを投げられちゃう
                    string cellValue = string.Empty;
                    if( temp != null)
                        cellValue = temp;
                    row.Add(cellValue);
                }
                rows.Add(row);
            }

            return rows;
        };

参考

UI Automation not working for DataGridView | stackoverflow
Getting full contents of a Datagrid using UIAutomation | stackoverflow
C# Windows Formアプリの部品DataGridViewに外部プロセスからアクセスしたい | stackoverflow

環境

  • Visual Studio 2015 SP1
  • Windows7 64bit

  1. 英語で結構引っかかるけど英語が出来ないので 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away