2013-04-10 29 views
9

Tôi đang học UI Automation và tôi thấy rằng bản sao "Inspect Object" của tôi hiển thị rằng IsKeyboardFocusable luôn luôn là sai ngay cả khi nó là đúng, tất cả các thông tin khác là giống nhau (như bạn có thể thấy từ hình ảnh). Có ai có bất kỳ ý tưởng tại sao tôi thấy tài sản này là sai khi tôi lấy giá trị?IsKeyboardFocusable là true trong Inspect Object nhưng luôn luôn sai trong ứng dụng của tôi

enter image description here

+0

Tôi gặp vấn đề tương tự. Đây là một vấn đề lớn bởi vì nếu 'IsKeyboardFocuseable' là sai gọi' SetFocus() 'sẽ ném một ngoại lệ. –

Trả lời

5

Trong ứng dụng Inspect Object phiên bản mới nhất của Windows Automation COM API (3.0) được sử dụng để hiển thị tất cả các thuộc tính này. Nhưng việc thực thi .NET UIAutomation mặc định không dựa trên giao diện COM của Windows Automation API 3.0 (nó dựa trên phiên bản trước của API COM này). Do đó một số thuộc tính không hoạt động chính xác. Ví dụ đối với danh sách liên hệ của Skype, thuộc tính AutomationElement.IsKeyboardFocusableProperty nói rằng việc nhận các giá trị cho thuộc tính này hoàn toàn không được hỗ trợ. Bạn có thể kiểm tra điều này bằng cách sử dụng đoạn mã sau:

object isKeyboardFocusable = listItem.GetCurrentPropertyValue(AutomationElement.IsKeyboardFocusableProperty, true); 
if(isKeyboardFocusable == AutomationElement.NotSupported) { 
    // we will always goes here 
} 

Hiện tại, tôi không biết cách nào để tránh hành vi này bằng cách sử dụng hiện tại .Net Triển khai UIAutomation.

Tin tốt là có triển khai Tự động hóa giao diện người dùng thay thế trong .NET. Có thể sử dụng giao diện COM của Windows Automation API 3.0 mới, với độ tin cậy và hiệu suất được cải thiện, trong khi vẫn sử dụng cùng System.Windows.Automation các lớp như trong các phiên bản trước của Tự động hóa giao diện người dùng. Triển khai này có sẵn dưới dạng dự án trên CodePlex: UI Automation COM-to-.NET Adapter

Vì vậy, hãy thử triển khai thay thế này ngay hôm nay và với việc triển khai thay thế này, thuộc tính IsKeyboardFocusable trả về kết quả tương tự như công cụ Inspect Objects! Hơn nữa, có thể sử dụng một số thuộc tính mở rộng có màn hình Inspect Objects (ví dụ: thành viên LegacyIAccessible).

3

Việc thực hiện nội bộ của IsKeyboardFocusable sử dụng GetCurrentPropertyValue (bất động sản: AutomationElement.IsKeyboardFocusableProperty, ignoreDefaultValue: false) chức năng. Trong trường hợp nó không thành công, nó chỉ trả về false (và trong trường hợp của bạn nó không thành công). Vì vậy, tôi khuyên bạn nên sử dụng GetCurrentPropertyValue (thuộc tính: AutomationElement.IsKeyboardFocusableProperty, ignoreDefaultValue: true) thay vì IsKeyboardFocusable, vì vậy bạn sẽ biết nếu nó không thành công.

Bạn có thể nhận được kết quả tương tự như Kiểm tra bằng cách sử dụng winapi. Olecc.dll cung cấp cho bạn IAccessible interface (Có chi tiết hơn description của giao diện này). Một thể hiện của giao diện đó có thể có các thể hiện con, một phần của chúng có thể được tập trung và một phần trong chúng - không. Nếu bạn tạo IAccessible từ HWnd, bạn không thể chắc chắn rằng toàn bộ điều khiển có thể lấy nét hoặc không lấy nét được. Để chắc chắn, bạn nên tạo IAccessible từ màn hình - nó cung cấp cho bạn chính xác IAccessible dưới điểm đó (Bạn có thể thấy trên ảnh chụp màn hình của mình, Inspect sử dụng điểm trên màn hình - "Cách tìm thấy - Di chuyển chuột (1120, 470)"). Ngoài ra, nếu bạn chuyển từ chế độ UIAutomation sang MSAA trong Inspect, bạn có thể thấy cách IAccessible trông như thế nào.

Nhưng nếu có thể trong trường hợp của bạn, tốt hơn nên sử dụng alternative implementation of UIAutomation. Nó trả về giá trị IsKeyboardFocusable chính xác (không giống như việc thực hiện UIAutomation chuẩn). Tôi đã không thử nghiệm thư viện này bản thân mình (tôi đã thử nghiệm chỉ IsKeyboardFocusable), nhưng có vẻ như nó hoạt động tốt, và nó có cùng loại và giao diện như việc thực hiện tiêu chuẩn. Như trong trường hợp IAccessible, bạn nên tạo AutomationElement từ một điểm, không phải từ HWnd.

Giới thiệu câu hỏi của bạn - Tôi chưa biết, tại sao UIAutomation chuẩn không thể trả về AutomationElement.IsKeyboardFocusableProperty corretly trong một số trường hợp. Tôi nghĩ, nó có thể là một lỗi.

+1

* Vui lòng * không sử dụng IAccessible. Đó là một API rất cũ, và có nhiều vấn đề (giao diện COM chatty, chặn tại các điểm không mong muốn, vv). Sử dụng liên kết UIAutomation thay thế. –

+0

@EricBrown: Tôi hoàn toàn đồng ý. Trong những trường hợp có thể, tốt hơn là sử dụng giao diện người dùng tự động hóa thay thế. Nhưng khi đây không phải là một lựa chọn, thì chỉ còn sử dụng IAccessible, và chỉ để tìm IsKeyBoardFocusable, nếu tiêu chuẩn UI Automation thất bại. –

+0

Win7 native proxy tự động hóa giao diện người dùng sẽ quay trở lại IAccessible; tuy nhiên, họ sử dụng IAccessible * inproc *, thay vì cross-proc, dẫn đến tăng hiệu suất lớn. Thực sự, hoàn toàn không có lý do gì cho các nhà phát triển viết các ứng dụng tự động hóa để sử dụng IAccessible. –

0

Bạn đã thử công cụ gián điệp Tự động hóa giao diện người dùng này: https://ddeltasolutions.000webhostapp.com/? Tôi tìm thấy trường hợp IsKeyboardFocusableProperty là đúng, ví dụ như thanh trình đơn của ứng dụng Skype.

Các vấn đề liên quan