简体   繁体   中英

ViewModel breaks UI automation in WPF

I have a WPF application that mostly follows MVVM, which I am trying to automate.

In some of my user controls I bind the Content property to the ViewModel of another user control. There is a data template defined which maps the ViewModel to the correct View to show on the screen.

This works fine for when the application is run by a user, but if I try to view the automation tree in UISpy or another tool, it always stops at the ViewModel.

I have found this problem in numerous places. Is there a way to tell the ViewModel to expose any automation properties beneath it in the tree? or am I defining the data template wrong?

Thanks in advance, Donal

EDIT: Here is a sample XAML taken from the app. It is blocking accessing the automation tree. It is placed inside a RibbonWindow.

<TabControl Grid.Column="2" 
   cal:RegionManager.RegionName="{x:Static Regions:RegionNames.MainRegion}"  
   Name="tabControlMain" 
   SelectedValuePath="Name">
       <TabControl.Template>
          <ControlTemplate TargetType="TabControl">
              <Grid>
                <TabPanel IsItemsHost="True" Visibility="Hidden" />
                <Border BorderBrush="{DynamicResource BorderBrush}" Background="White" BorderThickness="1">
                    <framework:CachingContentPresenter 
                        ItemsSource="{Binding Items, ElementName=tabControlMain}" 
                        ContentTemplateSelector="{framework:MvvmTemplateSelector}"
                        ContentSource="SelectedContent" />
                </Border>
              </Grid>
          </ControlTemplate>
     </TabControl.Template>

Below is a previous version of the above XAML. It was allowing access to the automation tree:

<TabControl 
     Grid.Column="2" 
     Padding="0" 
     cal:RegionManager.RegionName="{x:Static Regions:RegionNames.MainRegion}"  
     Name="tabControlMain" 
     TabStripPlacement="Bottom" 
     SelectedValuePath="Name" 
     ItemContainerStyle="{StaticResource TabItemStyle}">
</TabControl>

Where the TabItemStyle is:

<Style TargetType="{x:Type TabItem}" x:Key="TabItemStyle">
   <Setter Property="Template">
      <Setter.Value>
          <ControlTemplate TargetType="TabItem">
          </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

I managed to find a solution to the XAML posted above. I'm not sure if it will work in all cases in our app, but I have yet to try them properly.

Anyway, the fix was found in this post: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/fa8eb86f-5001-4af6-adb3-ceb0799a0cf3/

Basically, we added 'Name="PART_SelectedContentHost"' to the CachingContentPresenter in the ControlTemplate. From my understanding, this PART_ tells the parser/compiler to include the default behaviour of the control template such as mouse events and keyboard presses as well as Automation properties.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM