मैं Microsoft UI Automation का उपयोग कर रहा हूं (यानी AutomationElement) मेरे आवेदन के खिलाफ स्वचालित स्वीकृति परीक्षण चलाने के लिए। यह अच्छी तरह से चला गया है, लेकिन मैंने ऐसी स्थिति का सामना किया है जो स्वचालन ढांचे के संपर्क में नहीं आता है।

मेरे पास एक है ItemsControl (हालांकि मैं इसके व्युत्पन्न नियंत्रणों में से एक का उपयोग कर रहा था, जैसे ListBox) और मैं CollectionViewSource आइटम्स को ग्रुप करने के लिए। यहाँ प्रदर्शित करने के लिए एक पूर्ण विंडो है:

<Window x:Class="GroupAutomation.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Orchestra">
    <Window.Resources>

        <!-- Take some simple data -->
        <XmlDataProvider x:Key="SampleData" XPath="Orchestra/Instrument">
            <x:XData>
                <Orchestra xmlns="">
                    <Instrument Name="Flute" Category="Woodwind" />
                    <Instrument Name="Trombone" Category="Brass" />
                    <Instrument Name="French horn" Category="Brass" />
                </Orchestra>
            </x:XData>
        </XmlDataProvider>

        <!-- Add grouping -->
        <CollectionViewSource Source="{Binding Source={StaticResource SampleData}}" x:Key="GroupedView">
            <CollectionViewSource.GroupDescriptions>
                <PropertyGroupDescription PropertyName="@Category" />
            </CollectionViewSource.GroupDescriptions>
        </CollectionViewSource>
    </Window.Resources>

    <!-- Show it in an ItemsControl -->
    <ItemsControl ItemsSource="{Binding Source={StaticResource GroupedView}}" HorizontalAlignment="Left" Margin="4">
        <ItemsControl.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=Name}" FontWeight="Bold" />
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
            </GroupStyle>
        </ItemsControl.GroupStyle>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Border Padding="4" Margin="4" Background="#FFDEDEDE">
                    <StackPanel>
                        <Label Content="{Binding XPath=@Name}" />
                        <Button Content="Play" />
                    </StackPanel>
                </Border>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Window>

यह एक विंडो उत्पन्न करता है जिसमें उनकी श्रेणियों में समूहित आइटम होते हैं, और प्रत्येक आइटम में एक बटन होता है जिसे मैं UI ऑटोमेशन के साथ क्लिक करना चाहता हूं:

सूची के साथ विंडो का स्क्रीनशॉट
<उप>(स्रोत: brizzly.com)

हालांकि, अगर मैं UISpy.exe (या AutomationElement के साथ नेविगेट करें) मुझे केवल समूह दिखाई देते हैं (यहां तक ​​कि रॉ व्यू में भी):

UISpy
<उप>(स्रोत: brizzly.com)

जैसा कि आप देख सकते हैं, समूह तो हैं लेकिन उनमें कोई आइटम नहीं है, इसलिए बटन खोजने के लिए कहीं नहीं है। मैंने इसे डब्ल्यूपीएफ 3.5 एसपी1 और डब्ल्यूपीएफ 4.0 दोनों में आजमाया है और एक ही परिणाम प्राप्त किया है।

क्या समूहीकृत वस्तुओं पर UI स्वचालन का उपयोग करना संभव है, और यदि हां, तो कैसे?

7
GraemeF 5 मई 2010, 13:48
यहां दिखाए गए अनुसार सीधे आइटम नियंत्रण आइटम का उपयोग करें। लिंक
 – 
user1912383
20 पद 2016, 00:15

4 जवाब

मुझे इस समस्या का सामना करना पड़ा और मैंने http://www.colinsalmcorner.com/post/genericautomationpeer--helping-the-coded-ui-framework-find-your-custom-controls और एक जोड़ना GroupItems के लिए विशेष मामला।

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Automation;
using System.Windows.Automation.Peers;
using System.Windows.Media;
using System.Xml;

namespace ClassLibrary1
{
    public class MyItemsControl : ItemsControl
    {
        protected override AutomationPeer OnCreateAutomationPeer()
        {
            return new GenericAutomationPeer(this);
        }
    }

    public class GenericAutomationPeer : UIElementAutomationPeer
    {
        public GenericAutomationPeer(UIElement owner) : base(owner)
        {
        }

        protected override List<AutomationPeer> GetChildrenCore()
        {
            var list = base.GetChildrenCore();
            list.AddRange(GetChildPeers(Owner));
            return list;
        }

        private List<AutomationPeer> GetChildPeers(UIElement element)
        {
            var list = new List<AutomationPeer>();
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
            {
                var child = VisualTreeHelper.GetChild(element, i) as UIElement;
                if (child != null)
                {
                    AutomationPeer childPeer;
                    if (child is GroupItem)
                    {
                        childPeer = new GenericAutomationPeer(child);
                    }
                    else
                    {
                        childPeer = UIElementAutomationPeer.CreatePeerForElement(child);
                    }
                    if (childPeer != null)
                    {
                        list.Add(childPeer);
                    }
                    else
                    {
                        list.AddRange(GetChildPeers(child));
                    }
                }
            }
            return list;
        }
    }

}

मुझे आशा है कि इससे किसी को अभी भी उत्तर खोजने में मदद मिलेगी!

7
Trasvi 2 अगस्त 2016, 07:32
यह आदर्श नहीं है, लेकिन समूहीकृत ItemsControls के लिए AutomationPeer को ठीक करने के प्रयास को देखते हुए यह एक बहुत ही प्रभावी समाधान है। धन्यवाद!
 – 
grzegorz_p
10 नवम्बर 2016, 17:40

मैं बटनों के बारे में 100% निश्चित नहीं हूं, लेकिन TextBlock नियंत्रण जो DataTemplate के अंदर हैं, उन्हें UI ऑटोमेशन ट्री में नहीं रखा जाता है। जाहिरा तौर पर यह 1000 के असफल टेक्स्टब्लॉक से बचने के लिए एक अनुकूलन है।

आप सबक्लासिंग टेक्स्टब्लॉक द्वारा इसके आसपास काम कर सकते हैं। ये मेरा:

public class AutomatableTextBlock : TextBlock
{
    protected override AutomationPeer OnCreateAutomationPeer()
    {
        return new AutomatableTextBlockAutomationPeer(this);
    }

    class AutomatableTextBlockAutomationPeer : TextBlockAutomationPeer
    {
        public AutomatableTextBlockAutomationPeer(TextBlock owner)
            : base(owner)
        { }

        protected override bool IsControlElementCore()
        { return true; }
    }
}

नोट: यूआई ऑटोमेशन Canvas, Panel जैसे कई अन्य नियंत्रणों को भी उजागर नहीं करता है, आप उन्हें एक समान उपवर्ग के साथ दिखाने के लिए प्राप्त कर सकते हैं।

ऐसा कहकर, मुझे नहीं पता कि Button क्यों दिखाई नहीं दे रहा है.... Hrmmm

3
Orion Edwards 17 मई 2010, 07:00
समूहीकरण अक्षम होने पर मुझे जिन तत्वों की आवश्यकता होती है, वे ठीक दिखाई देते हैं, इसलिए मुझे नहीं लगता कि आपका उत्तर मदद करता है मुझे डर है। मैंने स्पष्टता के लिए उदाहरण में एक बटन का उपयोग किया क्योंकि वे हमेशा दिखाई देते हैं (इस मामले को छोड़कर!)
 – 
GraemeF
17 मई 2010, 16:04

मैंने टेम्पलेट खोजने के लिए AutomationElement.FindFirst का उपयोग करने के बाद पेड़ को मैन्युअल रूप से नेविगेट करने के लिए TreeWalker.RawViewWalker का उपयोग करके अपने आवेदन में इसे हल करना समाप्त कर दिया। ऐसा लगता है कि FindFirst किसी अन्य व्यक्ति के एप्लिकेशन को स्वचालित करते समय आपकी इच्छित सभी जानकारी को विश्वसनीय रूप से बहिष्कृत कर देता है। RawViewWalker काम करने लगता है जब तत्व "ऑब्जेक्ट्स का निरीक्षण" में दिखाई देते हैं, लेकिन UISpy या आपके एप्लिकेशन में नहीं।

2
mdonoughe 17 नवम्बर 2011, 23:13
इसने काम कर दिया! दिलचस्प तथ्य यह है कि UISpy को एक कंप्यूटर पर चाइल्ड नोड नहीं मिला लेकिन दूसरे पर मिला। दोनों कंप्यूटरों में समान विनिर्देश और समान सॉफ़्टवेयर स्थापित हैं। वैसे भी, ट्रीवॉकर के साथ ट्रिक ने दोनों के लिए काम किया।
 – 
SlavaGu
12 मार्च 2013, 08:09

स्वचालित स्क्रिप्ट लिखने के लिए आप किस टूल का उपयोग कर रहे हैं? मैंने सोचा होगा कि Win32 पेड़ (जैसा कि यूआईएसपी द्वारा सामने आया) पर भरोसा करने के बजाय डब्ल्यूपीएफ के लॉजिकल/विजुअल पेड़ में ड्रिल करने का विकल्प होगा।

यदि आप Snoop का उपयोग करके उसी एप्लिकेशन को देखते हैं, तो आपको पूर्ण दृश्य और तार्किक पेड़ दिखाई देंगे।

1
Tim Cooper 28 सितंबर 2011, 04:13
मैं MbUnit का उपयोग करके स्वीकृति परीक्षण लिख रहा हूं (लेकिन NUnit, xUnit.NET या जो भी हो सकता है) और UI ऑटोमेशन फ्रेमवर्क का उपयोग करके एप्लिकेशन चला रहा हूं। यह यूआई वस्तुओं से निपटने के द्वारा कार्यान्वयन (कुछ हद तक) से परीक्षणों को अलग करता है जिसे उपयोगकर्ता सीधे डब्ल्यूपीएफ पेड़ को देखने के बजाय देख सकता है और/या बातचीत कर सकता है। मैं इसे लगभग एक साल से कर रहा हूं और यह पहला मामला है जो मैंने पाया है कि "बस काम नहीं करता", इसलिए मैं इस स्तर पर स्विच फ्रेमवर्क के बजाय अंतर को प्लग करने की उम्मीद कर रहा हूं।
 – 
GraemeF
6 मई 2010, 15:21