0

我有一个 WPF 应用程序,我正在尝试使用FlaUI对其进行自动化。我正面临一个问题DxTabControl。我已经提供Automation IDsDxTabControl. 我正在使用动态DXTabControl.ItemHeaderTemplate生成TabItems。根据 DevExpress 团队的说法,DXTabControl.ItemHeaderTemplate不支持AutoamtionPeer因此添加了自定义实现来覆盖其默认行为。

TabControl现在,我可以看到TabItems. Inspect.exe现在,我的要求是访问当前选定的 Tabitem 并使用下面 XAML 中提到的 AutoamtionID 找到 CloseButton 并关闭它。再次粘贴到线下。由于会生成多个 TabItems,因此我无法获取 Current active/Selected TabItem

下面XAML

<dx:DXTabControl AutomationProperties.AutomationId="ViewsParentTabControl"
        MaxWidth="4000"
        MaxHeight="4000"
        Margin="1,0,-1,0"
        Focusable="False"
        ItemsSource="{Binding OpenViews}"
        SelectedIndex="{Binding SelectedTabIndex}"
        TabContentCacheMode="CacheTabsOnSelecting">
        <dx:DXTabControl.ItemHeaderTemplate>
            <DataTemplate DataType="viewModels1:OpenViewDefinitionViewModel">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <TextBlock Name="CreatedViewName"
                        MaxWidth="100"
                        Text="{Binding Data.ViewDefinition.Name}"
                        TextTrimming="CharacterEllipsis"
                        ToolTip="{Binding DisplayName}" />
                    <TextBlock Grid.Row="0" Grid.Column="1"><Run Text=" [" /><Run Text="{Binding ItemsCount, FallbackValue=0, Mode=OneWay}" /><Run Text="]" /></TextBlock>
                    <controls2:ProgressIndicator AutomationProperties.AutomationId="ProgressCurrentView"
                        Grid.Row="0"
                        Grid.Column="3"
                        Width="14"
                        Margin="4,0,0,0"
                        VerticalAlignment="Center"
                        CircleBorder="{StaticResource ListBoxItem.Foreground}"
                        CircleFill="{StaticResource ListBoxItem.Foreground}"
                        IndicatorEnabled="{Binding IsDataLoading}" />
                    <Button AutomationProperties.AutomationId="CloseCurrentViewButton"
                        Grid.Row="0"
                        Grid.Column="2"
                        Width="10"
                        Height="10"
                        Margin="10,1,0,0"
                        Padding="0"
                        HorizontalAlignment="Right"
                        BorderThickness="0"
                        Command="{Binding DataContext.CloseItemCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dx:DXTabControl}}"
                        CommandParameter="{Binding}"
                        Focusable="False"
                        Style="{StaticResource MwButtonStyle}"
                        ToolTip="Close">
                        <Path
                            Data="F1 M 26.9166,22.1667L 37.9999,33.25L 49.0832,22.1668L 53.8332,26.9168L 42.7499,38L 53.8332,49.0834L 49.0833,53.8334L 37.9999,42.75L 26.9166,53.8334L 22.1666,49.0833L 33.25,38L 22.1667,26.9167L 26.9166,22.1667 Z"
                            Fill="White"
                            Stretch="Fill" />
                    </Button>
                </Grid>
            </DataTemplate>
        </dx:DXTabControl.ItemHeaderTemplate>
        <dx:DXTabControl.ItemTemplate>
            <DataTemplate DataType="viewModels1:OpenViewDefinitionViewModel">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>

                    <local:VoyagesGridControl />

                    <local:VoyageValidationUserControl
                        Grid.Row="1"
                        Grid.Column="0"
                        MinHeight="100"
                        MaxHeight="300"
                        Visibility="{Binding Path=IsVoyageValidationShowing, FallbackValue=Collapsed, Converter={StaticResource BooleanToVisibilityConverter}}" />
                    <local:VoyageHistoryUserControl
                        Grid.Row="2"
                        Grid.Column="0"
                        MinHeight="300"
                        MaxHeight="300"
                        Visibility="{Binding Path=IsVoyageHistoryShowing, FallbackValue=Collapsed, Converter={StaticResource BooleanToVisibilityConverter}}" />
                    <local:VesselHistoryUserControl
                        Grid.Row="3"
                        Grid.Column="0"
                        MinHeight="300"
                        MaxHeight="300"
                        Visibility="{Binding Path=IsVesselHistoryShowing, FallbackValue=Collapsed, Converter={StaticResource BooleanToVisibilityConverter}}" />
                    <local:VoyageEvents
                        Grid.Row="0"
                        Grid.RowSpan="3"
                        Grid.Column="1"
                        VerticalAlignment="Top"
                        Visibility="{Binding Path=IsVoyageEventsShowing, FallbackValue=Collapsed, Converter={StaticResource BooleanToVisibilityConverter}}" />


                    <controls2:ProgressIndicator AutomationProperties.AutomationId="showProgressForLoadingViews"
                        Grid.Row="0"
                        Grid.RowSpan="3"
                        Grid.Column="0"
                        Width="80"
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        CircleBorder="{StaticResource ListBox.BorderBrush}"
                        CircleFill="{StaticResource ListBox.BorderBrush}"
                        IndicatorEnabled="{Binding IsDataLoading}" />
                    <!--  Buttons  -->
                    <Grid Grid.Row="4" Grid.Column="0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="Auto" />
                        </Grid.ColumnDefinitions>
                        <StackPanel
                            Grid.Column="0"
                            VerticalAlignment="Center"
                            Orientation="Horizontal">
                            <TextBlock Style="{StaticResource MwTextBlockLabelStyle}" Text="Last Refresh:" />
                            <TextBlock
                                Margin="2,0,4,0"
                                VerticalAlignment="Center"
                                Text="{Binding LoadDate, StringFormat=G}" />
                        </StackPanel>
                        <Button AutomationProperties.AutomationId="AddNewVoyageButton"
                            Grid.Row="0"
                            Grid.Column="1"
                            Padding="0"
                            Command="{Binding AddVoyagesCommand}"
                            Focusable="False"
                            Style="{StaticResource MwButtonStyle}"
                            ToolTip="Add a new voyage to this View (ALT + A)">
                            <StackPanel Orientation="Horizontal">
                                <ContentControl Height="26" Content="{StaticResource Add}" />
                                <Label Style="{StaticResource MwLabelStyle}">_Add</Label>
                            </StackPanel>
                        </Button>

                        <Button AutomationProperties.AutomationId="refreshVoyageButton"
                            Grid.Row="0"
                            Grid.Column="2"
                            Padding="0"
                            Command="{Binding RefreshVoyagesCommand}"
                            Focusable="False"
                            Style="{StaticResource MwButtonStyle}"
                            ToolTip="Refresh the this View (modified entries are left unchanged)">
                            <StackPanel Orientation="Horizontal">
                                <ContentControl Height="26" Content="{StaticResource Refresh}" />
                                <TextBlock Style="{StaticResource MwTextBlockLabelStyle}" Text="Refresh" />
                            </StackPanel>
                        </Button>

                        <Button AutomationProperties.AutomationId="showVoyageHistroyButton"
                            Grid.Column="4"
                            Margin="2,2,2,2"
                            Padding="0"
                            VerticalAlignment="Center"
                            Command="{Binding ShowVoyageHistoryCommand}"
                            Focusable="False"
                            ToolTip="Show the selected voyage's change history"
                            Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
                            <StackPanel Orientation="Horizontal">
                                <ContentControl Height="26" Content="{StaticResource ShowVoyageHistory}" />
                                <TextBlock
                                    Style="{StaticResource MwTextBlockLabelStyle}"
                                    Text="Hide Voyage History"
                                    Visibility="{Binding IsVoyageHistoryShowing, Converter={StaticResource BooleanToVisibilityConverter}}" />
                                <TextBlock
                                    Style="{StaticResource MwTextBlockLabelStyle}"
                                    Text="Show Voyage History"
                                    Visibility="{Binding IsVoyageHistoryShowing, Converter={StaticResource MwBoolToVisibilityConverterReverse}}" />
                            </StackPanel>
                        </Button>

                        <Button AutomationProperties.AutomationId="showVesselHistroyButton"
                            Grid.Column="5"
                            Margin="2,2,2,2"
                            Padding="0"
                            VerticalAlignment="Center"
                            Command="{Binding ShowVesselHistoryCommand}"
                            Focusable="False"
                            ToolTip="Show the selected vessel's voyage history"
                            Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
                            <StackPanel Orientation="Horizontal">
                                <ContentControl Height="26" Content="{StaticResource ShowVesselHistory}" />
                                <TextBlock
                                    Style="{StaticResource MwTextBlockLabelStyle}"
                                    Text="Hide Vessel History"
                                    Visibility="{Binding IsVesselHistoryShowing, Converter={StaticResource BooleanToVisibilityConverter}}" />
                                <TextBlock
                                    Style="{StaticResource MwTextBlockLabelStyle}"
                                    Text="Show Vessel History"
                                    Visibility="{Binding IsVesselHistoryShowing, Converter={StaticResource MwBoolToVisibilityConverterReverse}}" />
                            </StackPanel>
                        </Button>

                        <Button AutomationProperties.AutomationId="showVoyageButton"
                            Grid.Column="6"
                            Margin="2,2,2,2"
                            Padding="0"
                            VerticalAlignment="Center"
                            Command="{Binding ShowVesselVisitsCommand}"
                            Focusable="False"
                            ToolTip="Show the selected voyage's events"
                            Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
                            <StackPanel Orientation="Horizontal">
                                <ContentControl Height="26" Content="{StaticResource Anchor}" />
                                <TextBlock
                                    Style="{StaticResource MwTextBlockLabelStyle}"
                                    Text="Hide Voyage Events"
                                    Visibility="{Binding IsVoyageEventsShowing, Converter={StaticResource BooleanToVisibilityConverter}}" />
                                <TextBlock
                                    Style="{StaticResource MwTextBlockLabelStyle}"
                                    Text="Show Voyage Events"
                                    Visibility="{Binding IsVoyageEventsShowing, Converter={StaticResource MwBoolToVisibilityConverterReverse}}" />
                            </StackPanel>
                        </Button>

                        <Border Grid.Row="0" Grid.Column="8">
                            <Border.Style>
                                <Style TargetType="Border">
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding IsDuplicateView, Mode=TwoWay}" Value="true">
                                            <Setter Property="Background" Value="LightGreen" />
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </Border.Style>
                            <Button AutomationProperties.AutomationId="DuplicateCheckButton"
                                Padding="0"
                                Command="{Binding DuplicateVoyagesCommand}"
                                Focusable="False"
                                Style="{StaticResource MwButtonStyle}"
                                ToolTip="Switch to duplicate Voyages (ALT + D)"
                                Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
                                <StackPanel Orientation="Horizontal">
                                    <ContentControl Height="26" Content="{StaticResource Duplicate}" />
                                    <AccessText Style="{StaticResource MwAccessTextLabelStyle}" Text="{Binding VoyageDuplicateText}" />
                                </StackPanel>
                            </Button>
                        </Border>

                        <Button AutomationProperties.AutomationId="PublishVoyagesButton"
                            Grid.Row="0"
                            Grid.Column="9"
                            Padding="0"
                            Command="{Binding PublishVoyagesCommand}"
                            Focusable="False"
                            Style="{StaticResource MwButtonStyle}"
                            ToolTip="Publish any modified Voyages (ALT + P)"
                            Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
                            <StackPanel Orientation="Horizontal">
                                <ContentControl Height="26" Content="{StaticResource Publish}" />
                                <AccessText Style="{StaticResource MwAccessTextLabelStyle}" Text="{Binding VoyagePublishText}" />
                            </StackPanel>
                        </Button>

                        <Button AutomationProperties.AutomationId="UndoSingleVoyageButton"
                            Grid.Row="0"
                            Grid.Column="10"
                            Padding="0"
                            Command="{Binding UndoSingleChangedVoyagesCommand}"
                            Focusable="False"
                            Style="{StaticResource MwButtonStyle}"
                            ToolTip="Locally Undo unpublished changes to the selected voyage"
                            Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
                            <StackPanel Orientation="Horizontal">
                                <ContentControl Height="26" Content="{StaticResource Undo}" />
                                <TextBlock Style="{StaticResource MwTextBlockLabelStyle}" Text="Undo Selected" />
                            </StackPanel>
                        </Button>

                        <Button AutomationProperties.AutomationId="UndoandUnpublishVoyageButton"
                            Grid.Row="0"
                            Grid.Column="11"
                            Padding="0"
                            Command="{Binding UndoChangedVoyagesCommand}"
                            Focusable="False"
                            Style="{StaticResource MwButtonStyle}"
                            ToolTip="Locally Undo any changed and unpublished voyages"
                            Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
                            <StackPanel Orientation="Horizontal">
                                <ContentControl Height="26" Content="{StaticResource Undo}" />
                                <TextBlock Style="{StaticResource MwTextBlockLabelStyle}" Text="Undo All" />
                            </StackPanel>
                        </Button>
                    </Grid>
                </Grid>
            </DataTemplate>
        </dx:DXTabControl.ItemTemplate>
    </dx:DXTabControl>

FlaUI定位控件的方法如下

public IMainWindow ConfirmCreatedView()
        {
            _logger.Info("Checking the newly created View on the screen");
            //Apoorv: Need to find TabItem here
            _controlAction.Highlight(ViewsTabControl); // This highlights the TabControl- Works
            int NumberOfActiveTabs = ViewsTabControl.TabItems.Length; // This gives me no of TabItems


          TabItem SelectedTab=  ViewsTabControl.SelectedTabItem as TabItem; // Gives me Null here
            var newTab = ViewsTabControl.SelectedTabItemIndex ; // Give me -1 here


            _controlAction.Highlight(ViewsTabControl.TabItems[2]); // Works. It highlights the TabItem at position 2

            _controlAction.ClickWait<TabItem>(ViewsTabControl.TabItems[2]); // This goes and clicks the tab item 

            TabItem SelectedTabs = ViewsTabControl.SelectedTabItem as TabItem;
            var check = ViewsTabControl.TabItems[2].FindAllChildren();
            // TabItem ti = ViewsTabControl.SelectedItem as TabItem;
            //_controlAction.Highlight()



                _controlAction.Highlight(CloseCurrentView); // highlights the close button atTabItem[0]
                _controlAction.Click<Button>(CloseCurrentView); // closes it

                      return this;
        }

我正在使用FlaUI查找TabControl使用AutomationID,如下所示

 private Tab ViewsTabControl => _uiAutomation.FindElement("ViewsParentTabControl", Automation.FindBy.Id).AsTab();
        private TabItem ViewsTabItem => _uiAutomation.FindElement("DXTabItem", Automation.FindBy.Id).AsTabItem();

我想TabItem根据索引找到当前活跃的,然后通过自动化点击关闭按钮。

TabItem SelectedTab=  ViewsTabControl.SelectedTabItem as TabItem; // Gives me Null here
            var newTab = ViewsTabControl.SelectedTabItemIndex ; // Give me -1 here
4

2 回答 2

0

DevEXpress不要automation peersItemHeaderTemplate. 有必要使用 acustom automation peer来提供此功能。例如,我将以下类用于测试目的:

public class DXTabItemAutomationPeerEx : DXTabItemAutomationPeer, ISelectionItemProvider {
    private DXTabItem TabItem => base.Owner as DXTabItem;
    private DXTabControl TabControl => TabItem.With((DXTabItem x) => x.Owner);
    public DXTabItemAutomationPeerEx(DXTabItem ownerCore) : base(ownerCore) { }
    protected override List<AutomationPeer> GetChildrenCore() {
        List<AutomationPeer> children = base.GetChildrenCore();
        foreach (var button in LayoutTreeHelper.GetVisualChildren(Owner).OfType<Button>())
            children.Add(new ButtonAutomationPeer(button));
        return children;
    }
    bool ISelectionItemProvider.IsSelected { get {
            if (TabControl != null) {
                return TabControl.SelectedContainer == TabItem;
            }
            return false;
        } 
    }
}

在我的内部添加此代码后MainPage.Xaml.cs,我添加了static constructor一个register

static MainWindow() {
    NavigationAutomationPeersCreator.Default.RegisterObject(typeof(DXTabItem), typeof(DXTabItemAutomationPeerEx), owner => new DXTabItemAutomationPeerEx((DXTabItem)owner));
}

发布这个,这些线条很有魅力

TabItem CurrentTab = ViewsTabControl.SelectedTabItem as TabItem;
var Children = ViewsTabControl.FindAllChildren(); 
foreach (var child in Children) {
    var subChildren = child.FindAllChildren();
}
于 2020-02-17T16:19:19.087 回答
0

它不是 TabItem,而是 DXTabItem。这是您应该转换为的类型。

DXTabItem SelectedTab = ViewsTabControl.SelectedTabItem as DXTabItem;
于 2020-02-13T08:50:46.713 回答