How to access to WPF objects properties, inside in a ListBox

Apr 8, 2010 at 6:47 PM

I have the following code, and I want to click a hyperlynk that is inside a TabControl. All the TabControls are in a ListBox, so i want to filter by the text of this hyperlinks, but I can't access to the properties. Since Iimplemented White, I can manage actions (click, DoubleClick, etc.) but I've never could see the properties. In this case I could get the hyperlink from the Tab from the ListBox, but I can not access to the properties.

This is the code of the ListBox (I am using Templates and styles)

            <ListBox 
                x:Name="AppItemListBox"
                ItemsSource="{Binding ApplicationList}"
                ItemTemplate="{Binding Path=DefaultItemDataTemplateValue, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type UserControl}}}"
                Style="{Binding Path=DefaultListStyleValue, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type UserControl}}}">
            </ListBox>




Now I am getting a ListBoxItem with hardcode, selecting by index, but I want to filter by the hyperlink context
      ListBox appItemListBox=_appUpWindow.Get<ListBox>("AppItemListBox"); 
      ListItems items = appItemListBox.Items; 
      WPFListItem wpfListItem = (WPFListItem)items.Item(1); 
      var hyperlink = wpfListItem.Get<Hyperlink>(SearchCriteria.All); 
      hyperlink.Click(); 

I tried like this but it is not working:
            ListBox appItemListBox = _appUpWindow.Get<ListBox>("AppItemListBox");
            ListItems items = appItemListBox.Items;
            for (int i = 0; i < items.Count; i++)
            {
                WPFListItem wpfListItem = (WPFListItem)appItemListBox.Item(i);
                var hyperlink = wpfListItem.Get<Hyperlink>(SearchCriteria.ByText("TEXT that I am looking for!"));
                if (hyperlink != null)
                {
                    hyperlink.Click();
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("the search was not successful");
                }
            }

Coordinator
Apr 11, 2010 at 5:41 AM

Text criteria in white maps to Name property in UIA. can you use UISpy/UIAutomationVerify and see what value it shows for the hyperlink.

 

Apr 21, 2010 at 3:53 PM

I could not see it with UISpy, the problem is that you can not identify an object that is in a Template. Check this code:

This is the XAML, the View

<Window x:Class="WPFApp.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:WPFApp="clr-namespace:WPFApp"
    Title="Window1" Height="300" Width="300">
   
    <Grid>
        
        <Grid.Resources>
            <Style TargetType="{x:Type WPFApp:CustomListBox}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type WPFApp:CustomListBox}">
                            <Grid x:Name="templateGrid">
                                <Grid.RowDefinitions>
                                    <RowDefinition/>
                                    <RowDefinition/>
                                    <RowDefinition/>
                                </Grid.RowDefinitions>
                                <TextBox x:Name="templateTextBox" Grid.Row="0">TextBox in Template</TextBox>
                                <Button x:Name="templateButton" Grid.Row="1">Button in Template</Button>
                                <StackPanel x:Name="temaplateStackPanel" Grid.Row="2">
                                    <ItemsPresenter x:Name="templateItemPresenter"/>
                                </StackPanel>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Grid.Resources>
        
        <WPFApp:CustomListBox x:Name="myCustomListBox">
            <!-- I put the property x:name to generate the AutomationId -->
            <ListBoxItem x:Name="myListBoxItemOne">One</ListBoxItem>
            <ListBoxItem x:Name="myListBoxItemTwo">Two</ListBoxItem>
            <ListBoxItem x:Name="myListBoxItemThree">Three</ListBoxItem>
        </WPFApp:CustomListBox>

    </Grid>
</Window>


The CustomListBox is just a ListBox:
namespace WPFApp
{
 
    public class CustomListBox : ListBox
    {
        static CustomListBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomListBox), new FrameworkPropertyMetadata(typeof(CustomListBox)));
        }
    }
}


If I try to run a Test with White, I am not being able to see the UI Objects!!!
    public class UnitTest1
    {
        Window _appUpWindow;

        public UnitTest1()
        {
            Application application = Application.Launch(@"C:\Documents and Settings\bmatias\Desktop\WPFApp-My with WHITE\WPFApp\WPFApp\bin\Debug\WPFApp.exe");
            Assert.IsNotNull(application, "Could not get the Application");

            System.Threading.Thread.Sleep(2000);

            _appUpWindow = application.GetWindow("Window1", InitializeOption.NoCache);
            _appUpWindow.LogStructure();
            Assert.IsNotNull(_appUpWindow, "Could not Get the Window1");
        }


        [TestMethod]
        public void TestMethod1()
        {
            //not included in the template
            ListItem myListBoxItemOne = _appUpWindow.Get<ListItem>("myListBoxItemOne");
            Assert.IsNotNull(myListBoxItemOne, "Could not find TextBox -myListBoxItemOne- by its Name");
            myListBoxItemOne.Click();

            System.Threading.Thread.Sleep(2000);

            //included in the template
            TextBox templateTextBox = _appUpWindow.Get<TextBox>("templateTextBox");
            Assert.IsNotNull(templateTextBox, "Could not find TextBox -templateTextBox- by its Name");
            templateTextBox.Text = "I am ADDING this text from the UnitTest1 !!!";

            //included in the template
            Button templateButton = _appUpWindow.Get<Button>("templateButton");
            Assert.IsNotNull(templateButton, "Could not find Button -templateButton- by its Name");
            templateButton.Click();

            System.Threading.Thread.Sleep(2000);

            _appUpWindow.Close();
        }
 

Apr 21, 2010 at 4:03 PM

Hi

 

if you could not see it with uispy there is no way to handle it with UIAutomation.

If you develop the application yourself or you have access to the developer, than:

 

Have a look for Custom Controls and your own implementation of AutomationPeer

 

and have a look here: WPF on Codeplex

 

Throndorin

 

 

Apr 21, 2010 at 4:25 PM

This project is just an example, and the real project is really big and it is in production, for this reason the idea is not to modify the source code. And the changes would be really big to implement the AutomationPeer.

And I have been researching and if you just complete the property name or x:name, the AutomationID is generated automatically.

 

Apr 22, 2010 at 8:24 AM

You can define name and such things for many objekts in WPF

 

for example for elements which inherit class Control

 

but Control does not implement Automation Peer and so you can not see these elements.

 

So:

 

To have an automationId is not the reason to see the element in UISpy or with UIAutomation, only the implementation of the Automation Peer gives UISpy as Client a chance to see the element.

 

Throndorin