2013-04-10 17 views
9

Sto imparando l'automazione dell'interfaccia utente e ho scoperto che il mio clone "Inspect Object" sta mostrando che IsKeyboardFocusable è sempre falso anche quando è vero, tutte le altre informazioni sono identiche (come puoi vedere dall'immagine). Qualcuno ha qualche idea del perché vedo questa proprietà come falsa quando recupero il valore?IsKeyboardFocusable è true in Inspect Object ma è sempre falso nella mia applicazione

enter image description here

+0

Ho lo stesso identico problema. Questo è un grosso problema perché se 'IsKeyboardFocuseable' è una falsa chiamata' SetFocus() 'genererà un'eccezione. –

risposta

5

Nell'applicazione Inspect Object viene utilizzata l'ultima versione dell'API COM di Windows Automation (3.0) per visualizzare tutte queste proprietà. Tuttavia, l'implementazione UIAutomation .NET predefinita non è basata sulle interfacce COM di Windows Automation API 3.0 (basate sulla versione precedente di questa API COM). Quindi alcune proprietà non sono funzionanti correttamente. Ad esempio, per l'elenco dei contatti di Skype, la proprietà AutomationElement.IsKeyboardFocusableProperty afferma che l'acquisizione di valori per questa proprietà non è supportata affatto. È possibile controllare questo utilizzando il seguente frammento di codice:

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

In questo momento, non so modi per evitare questo comportamento utilizzando l'implementazione corrente .Net UIAutomation.

Le buone notizie sono che esiste un'implementazione di automazione dell'interfaccia utente alternativa in .NET che rende possibile l'utilizzo delle nuove interfacce COM di Windows Automation API 3.0, con la loro affidabilità e prestazioni migliorate, mentre si utilizza ancora lo stesso System.Windows.Automation classi come nelle versioni precedenti di UI Automation. Questa implementazione è disponibile come progetto su CodePlex: UI Automation COM-to-.NET Adapter

Quindi, ho provato quest'implementazione alternativa oggi, e con questa implementazione alternativa la proprietà IsKeyboardFocusable restituisce lo stesso risultato dello strumento Inspect Objects! Inoltre ora è possibile utilizzare alcune proprietà estese che vengono visualizzate negli schermi Inspect Objects (ad esempio membri LegacyIAccessible).

3

L'implementazione interna di IsKeyboardFocusable utilizza GetCurrentPropertyValue (proprietà: AutomationElement.IsKeyboardFocusableProperty, ignoreDefaultValue: false) funzione. Nei casi in cui fallisce, restituisce semplicemente false (e nel tuo caso fallisce). Pertanto, ti consiglio di utilizzare GetCurrentPropertyValue (proprietà: AutomationElement.IsKeyboardFocusableProperty, ignoreDefaultValue: true) anziché IsKeyboardFocusable, in modo che tu sappia se fallisce.

È possibile ottenere esattamente lo stesso risultato di Inspect utilizzando winapi. Olecc.dll ti dà IAccessible interface (C'è più dettagliato description di questa interfaccia). Un'istanza di tale interfaccia può avere istanze di bambini, parte di esse può essere focalizzabile e parte di esse - non. Se crei IAccessible da HWnd, non puoi essere sicuro che l'intero controllo sia focalizzabile o non focalizzabile. Per essere sicuro, dovresti creare IAccessible dal punto dello schermo - ti dà esattamente l'IAccessibilità che sotto quel punto (puoi vedere sul tuo screenshot, che Inspect usa il punto sullo schermo - "Come trovato - Muovi il mouse (1120, 470)"). Inoltre, se si passa dalla modalità UIAutomation a MSAA in Inspect, è possibile vedere come appare IAccessible.

Ma, se è possibile nel tuo caso, è meglio usare alternative implementation of UIAutomation. Restituisce il valore IsKeyboardFocusable corretto (diversamente dall'implementazione standard di UIAutomation). Non ho provato questa libreria da solo (ho testato solo IsKeyboardFocusable), ma sembra che funzioni bene e che abbia gli stessi tipi e interfacce dell'implementazione standard. Come nel caso IAccessible, è necessario creare AutomationElement da un punto, non da HWnd.

Informazioni sulla tua domanda - Non so ancora, perché UIAutomation standard non può restituire correttamente AutomationElement.IsKeyboardFocusableProperty in alcuni casi. Penso che potrebbe essere un bug.

+1

* Per favore * non usare IAccessible. È un'API molto vecchia e presenta numerosi problemi (interfacce COM chatty, blocchi a punti imprevisti, ecc.). Utilizzare il legame alternativo UIAutomation. –

+0

@EricBrown: sono completamente d'accordo. Nei casi in cui è possibile, è preferibile utilizzare l'automazione dell'interfaccia utente alternativa. Ma quando questa non è un'opzione, allora rimane solo da usare IAccessible e solo per trovare IsKeyBoardFocusable, se l'automazione dell'interfaccia utente standard fallisce. –

+0

I proxy di automazione nativa di Win7 torneranno a IAccessible; tuttavia, usano IAccessible * inproc *, piuttosto che cross-proc, il che si traduce in un massiccio aumento delle prestazioni. In realtà, non c'è assolutamente alcun motivo per gli sviluppatori che scrivono applicazioni di automazione per utilizzare IAccessible. –

0

Avete provato questo strumento spia di automazione interfaccia utente: https://ddeltasolutions.000webhostapp.com/? Ho trovato casi in cui IsKeyboardFocusableProperty è true, ad esempio la barra dei menu dell'applicazione Skype.

Problemi correlati