Jaws screen reader /Narrator does not read selected value of combo box control which contains tree view control in wpf

Ajay Gera 40 Reputation points
2024-10-08T14:42:51.84+00:00

Hi,

I have created one combo box control and inside ComboBox.Template I have added one tree view control. Basically one Combobox user control which on expanding shows contents as treeview control.

Combox selected item is bound with item which is selected by Treeview control. i.e. after expanding Combobox control , user selects item from Treeview control and that item gets displayed in the Combox box control.

Here issue is Jaws screen reader/Narrator does not read text which is shown by combo box control.

Please note, jaws screen reader reads selected content/text of Treeview control but it does not read value from the Combobox control which gets displayed after selecting content/text from Treeview control

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,783 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Hongrui Yu-MSFT 2,465 Reputation points Microsoft Vendor
    2024-10-09T08:21:05.13+00:00

    Hi,@Ajay Gera. Welcome to Microsoft Q&A. 

    Solution: You could temporarily store the TreeView selected Item in a variable through the SelectedItemChanged event, and then bind the variable to the AutomationProperties.Name of the ComboBox through data binding to achieve the effect you want.

     

    Assume Category is the data type stored in TreeView.ItemsSource, and the temporary variable is SelectedCategory(used to store the value selected by TreeView)

    
    public class Category
    
    {
    
        public string Name { get; set; }
    
        public ObservableCollection<Category> Items { get; set; }
    
    }
    
    

     

    
    public string selectedCategory;
    
    public string SelectedCategory { get { return selectedCategory; } set { selectedCategory = value; OnPropertyChanged("SelectedCategory"); } }
    
    

     

    The SelectedItemChanged event of the TreeView changes the SelectedCategory to the currently selected value.

    
    private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    
    {
    
        var treeView = sender as TreeView;
    
        if(treeView!=null)
    
        {
    
            SelectedCategory = (treeView.SelectedItem as Category).Name;
    
        }
    
    }
    
    

    Finally bind SelectedCategory to ComboBox

    
    <ComboBox AutomationProperties.Name="{Binding SelectedCategory}" … >
    
    

     

     

    The complete code is as follows.

    MainWindow.xaml

    
    <Grid>
    
        <ComboBox x:Name="MyComboBox"  Width="200" Height="40" HorizontalAlignment="Center" VerticalAlignment="Center" AutomationProperties.Name="{Binding SelectedCategory}" >
    
            <ComboBox.Template>
    
                <ControlTemplate TargetType="ComboBox">
    
                    <Grid>
    
                        <ToggleButton Name="ToggleButton"  Focusable="false" IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press"/>
    
                        <ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{Binding Path=SelectedItem.Name,ElementName=MyTreeView}"  Margin="3,3,23,3" VerticalAlignment="Center" HorizontalAlignment="Left" />
    
                        <Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsDropDownOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Slide" Margin="61,-34,-61,34">
    
                            <Grid Name="DropDown" SnapsToDevicePixels="True" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}">
    
                                <Border x:Name="DropDownBorder" />
    
                                <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
    
                                    <TreeView x:Name="MyTreeView" ItemsSource="{Binding Path=ItemsSource,RelativeSource={RelativeSource AncestorType=ComboBox, AncestorLevel=1,Mode=FindAncestor}}" SelectedItemChanged="TreeView_SelectedItemChanged">
    
                                        <TreeView.ItemTemplate>
    
                                            <HierarchicalDataTemplate ItemsSource="{Binding Items}">
    
                                                <TextBlock Text="{Binding Name}" />
    
                                            </HierarchicalDataTemplate>
    
                                        </TreeView.ItemTemplate>
    
                                        <TreeView.ItemContainerStyle>
    
                                            <Style TargetType="TreeViewItem">
    
                                                <Setter Property="AutomationProperties.Name" Value="{Binding Name}"></Setter>
    
                                            </Style>
    
                                        </TreeView.ItemContainerStyle>
    
                                    </TreeView>
    
                                </ScrollViewer>
    
                            </Grid>
    
                        </Popup>
    
                    </Grid>
    
                </ControlTemplate>
    
            </ComboBox.Template>
    
        </ComboBox>
    
    </Grid>
    
    

     

    MainWindow.xaml.cs

    
       public partial class MainWindow : Window, INotifyPropertyChanged
    
       {
    
           public ObservableCollection<Category> Categories { get; set; }
    
     
    
           public string selectedCategory;
    
           public string SelectedCategory { get { return selectedCategory; } set { selectedCategory = value; OnPropertyChanged("SelectedCategory"); } }
    
     
    
           public event PropertyChangedEventHandler? PropertyChanged;
    
     
    
           public MainWindow()
    
           {
    
               Categories = new ObservableCollection<Category>
    
               {
    
                   new Category
    
                   {
    
                       Name = "Category1",
    
                       Items = new ObservableCollection<Category>
    
                       {
    
                             new Category { Name = "Item1",Items = new ObservableCollection<Category>() },
    
                             new Category { Name = "Item2",Items = new ObservableCollection<Category>() }
    
                       }
    
                   },
    
                   new Category
    
                   {
    
                       Name = "Category2",
    
                       Items = new ObservableCollection<Category>
    
                       {
    
                             new Category { Name = "Item3" },
    
                             new Category { Name = "Item4" }
    
                       }
    
                   }
    
               };
    
               InitializeComponent();
    
               this.DataContext = this;
    
               MyComboBox.ItemsSource = Categories;
    
           }
    
     
    
           public void OnPropertyChanged([CallerMemberName]string propertyName="")
    
           {
    
               PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    
           }
    
     
    
           private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    
           {
    
               var treeView = sender as TreeView;
    
               if(treeView!=null)
    
               {
    
                   SelectedCategory = (treeView.SelectedItem as Category).Name;
    
               }
    
           }
    
       }
    
       public class Category
    
       {
    
           public string Name { get; set; }
    
           public ObservableCollection<Category> Items { get; set; }
    
       }
    
    

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.