【问题标题】:UI Automation - Set Text for a another application's TextBoxUI 自动化 - 为另一个应用程序的 TextBox 设置文本
【发布时间】:2019-05-18 23:05:56
【问题描述】:

我有两种形式。当单击其中一个按钮时,我想打开另一个按钮并在其中填充一个文本框。我尝试使用下面的代码,但它给出了“不支持的模式”的错误。

这是我的代码:

private void button1_Click(object sender, EventArgs e)
{
    string automationId = "Form1";
    string newTextBoxValue = "user1";
    var condition = new PropertyCondition(AutomationElement.AutomationIdProperty, automationId);
    var textBox = AutomationElement.RootElement.FindFirst(TreeScope.Subtree, condition);
    ValuePattern vPattern = (ValuePattern)textBox.GetCurrentPattern(ValuePattern.Pattern);
    vPattern.SetValue(newTextBoxValue);
}

【问题讨论】:

  • 你的问题不够清楚。这两个表单是在同一个项目中还是两个表单来自两个不同的应用程序?
  • @preciousbetine 你对歧义是正确的,但我怀疑 OP 混淆了表格和应用程序。我怀疑他想连接到另一个应用程序并在那里设置一个文本框。

标签: c# .net winforms ui-automation


【解决方案1】:

您应该首先检查ValuePattern 模式的可用性:

  • 如果ValuePattern 模式可用,请使用其SetValue 方法。
  • 否则,请使用以下解决方案之一:
    1. 将焦点设置到控件并使用SendKeys 清除和设置文本。
    2. 或者使用SendMessage并发送WM_SETTEXT消息来设置文本,

示例

var notepad = System.Diagnostics.Process.GetProcessesByName("notepad").FirstOrDefault();
if (notepad != null)
{
    var root = AutomationElement.FromHandle(notepad.MainWindowHandle);
    var element = root.FindAll(TreeScope.Subtree, Condition.TrueCondition)
                        .Cast<AutomationElement>()
                        .Where(x => x.Current.ClassName == "Edit" &&
                                    x.Current.AutomationId == "15").FirstOrDefault();
    if (element != null)
    {
        if (element.TryGetCurrentPattern(ValuePattern.Pattern, out object pattern))
        {
            ((ValuePattern)pattern).SetValue("Something!");
        }
        else
        {
            element.SetFocus();
            SendKeys.SendWait("^{HOME}");   // Move to start of control
            SendKeys.SendWait("^+{END}");   // Select everything
            SendKeys.SendWait("{DEL}");     // Delete selection
            SendKeys.SendWait("Something!");

           // OR 
           // SendMessage(element.Current.NativeWindowHandle, WM_SETTEXT, 0, "Something!");
        }
    }
}

如果使用SendMessage,请确保将以下声明添加到类中:

[System.Runtime.InteropServices.DllImport("User32.dll")]
static extern int SendMessage(int hWnd, int uMsg, int wParam, string lParam);
const int WM_SETTEXT = 0x000C;

您可以阅读该方法:

【讨论】:

  • dash damet garm ok shod
【解决方案2】:

首先,您应该获得要打开的第二个表单的句柄。如果之前创建并存储为类变量,则使用它,否则在此方法中创建并打开它。

为了让您能够在另一个表单中填充文本框,您需要将它的访问器设置为公共,或者为其创建一个公共的 setter 方法。

private void button1_Click(object sender, EventArgs e)
{
    string automationId = "Form1";
    string newTextBoxValue = "user1";
    var condition = new PropertyCondition(AutomationElement.AutomationIdProperty, automationId);
    var textBox = AutomationElement.RootElement.FindFirst(TreeScope.Subtree, condition);
    ValuePattern vPattern = (ValuePattern)textBox.GetCurrentPattern(ValuePattern.Pattern);
    vPattern.SetValue(newTextBoxValue);

    // this is the idea, not tested, adjust it to yourself
    var form2 = new SecondForm();
    form2.YourTextBox.Text = newTextBoxValue;
    form2.Show();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-05
    • 1970-01-01
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    • 2021-02-13
    相关资源
    最近更新 更多