Accessibility insights for windows app shows error for datagrid- custom column and other columns for name property of focusable element is null - datagrid

I'm trying to fix the accessibility bugs I found in Accessibility insights for windows app for my desktop application.
Here is my code for datagrid-
<controls:DataGrid
x:Uid="DataTable"
x:Name="detailGrid"
Margin="0"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible"
AreRowDetailsFrozen="False"
AreRowGroupHeadersFrozen="True"
AutoGenerateColumns="False"
CanUserSortColumns="True"
CanUserReorderColumns="True"
CanUserResizeColumns="True"
ColumnHeaderHeight="28"
MaxColumnWidth="500"
FrozenColumnCount="0"
GridLinesVisibility="None"
HeadersVisibility="Column"
IsReadOnly="False"
RowDetailsVisibilityMode="Collapsed"
SelectionMode="Extended"
SelectionChanged="OnDataGridSelectionChanged"
RowHeight="25"
RowGroupHeaderPropertyNameAlternative="Range"
ItemsSource="{x:Bind ViewModel.GridData}" Visibility="{x:Bind ViewModel.IsContentVisible, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}">
<controls:DataGrid.Columns>
<controls:DataGridTemplateColumn Header="Name">
<controls:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Margin="10,0,0,0" Width="15" Source="../Assets/folder.png" Visibility="{Binding ChildFolder.IsFolder, Converter={StaticResource BoolToVisibilityConverter}}" />
<Image Margin="10,0,0,0" Width="15" Source="../Assets/file.png" Visibility="{Binding ChildFolder.IsFolder, Converter={StaticResource BoolToInverseVisibilityConverter}}" />
<HyperlinkButton Height="28" FontFamily="Segoe" Content="{Binding ChildFolder.FolderName}" Margin="0" FontSize="12px" Tapped="onSingleTapped" DoubleTapped="onDoubleTapped" IsDoubleTapEnabled="True" CommandParameter="{Binding ChildFolder}" HorizontalAlignment="Stretch">
</HyperlinkButton>
</StackPanel>
</DataTemplate>
</controls:DataGridTemplateColumn.CellTemplate>
</controls:DataGridTemplateColumn>
<!--<controls:DataGridTextColumn Binding="{Binding ChildFolder.BlobType}" Header="Blob Type" />-->
<controls:DataGridTextColumn Binding="{Binding ChildFolder.LastModifiedLocal}" Header="Last Modified" />
<controls:DataGridTextColumn Binding="{Binding ChildFolder.ContentTypeDisplay}" Header="Content Type" />
<controls:DataGridTextColumn Binding="{Binding ChildFolder.ContentSize}" Header="Size" />
<controls:DataGridTextColumn Binding="{Binding ChildFolder.LeaseStateString}" Header="Lease State" />
</controls:DataGrid.Columns>
</controls:DataGrid>
Can someone please let me know how I can fix the above bug as I'm working first time on windows accessibility?
These are the documentation that it asks to refer but I'm not sure how to fix it.
https://learn.microsoft.com/en-us/accessibility-tools-docs/items/uwpxaml/customcontrol_localizedcontroltype
https://learn.microsoft.com/en-us/accessibility-tools-docs/items/uwpxaml/customcontrol_name

Based on the screenshot you provide, this error is coming from the LocalizedControlTypeNotCustom rule. It's hard to tell for sure from just the screenshot and the XAML, but I would guess that UWP is creating a custom control based on your data template. If an AT user navigates to the group, then the control type will be read as "Custom", which provides no indication of how to interact with this element. If that's truly the case, then it might be possible to specify the element as a Group by setting the AutomationProperties.Name in the data template.
That's about all I can offer from the information that you've provided. If you can create a minimal repro app, then share it in a gist or a public repo, we can try to shed more light on specific ways to address this.
--Dave Tryon
Accessibility Insights team

Related

Xamarin CollectionView event and command issue

I work on the front end of our app, configuring the UI. Our app originally had a ListView using Xamarin Community Toolkit's EventToCommandBehavior with custom ViewCells to facilitate the search. We set up custom renderers to change the ViewCell's background color. However, when I moved over to the Mac, we discovered that none of that worked with iOS; the cell background would not change.
At this point, I switched to a CollectionView with a TapGestureRecognizer on the grid using VisualStateManager to change the background color. Since then, I can either get the grid selection to highlight without the command enabling our buttons or the command to fire which enables the buttons, but the grid selection will not highlight. Simply put, I either get the command or the event but have been unable to get them working together. This is also a problem on our store page; the IAP's never highlighted before the purchase confirmation popped up. We have been experiencing this issue from the start and never noticed.
Here is the relevant XAML:
<!--Faction Search Results-->
<Frame Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="6" BackgroundColor="Black" BorderColor="White" CornerRadius="5">
<CollectionView ItemsSource="{Binding FactionItems}"
BackgroundColor="Transparent">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid x:DataType="Data:Faction" BackgroundColor="Black">
<Grid.GestureRecognizers>
<TapGestureRecognizer
NumberOfTapsRequired="1"
Command="{Binding Source={RelativeSource AncestorType={x:Type local:FactionTopPageViewModel}}, Path=ItemTapped}"
CommandParameter="{Binding .}">
</TapGestureRecognizer>
</Grid.GestureRecognizers>
<Grid.RowDefinitions>
<RowDefinition Height="{markups:OnScreenSize DefaultSize='12', iPod='20', iPhoneSE='20', iPhoneXR='20', iPhoneX='20', iPhone13='25', iPhone7p='25', iPhone11pm='25', iPhone13pm='16',
iPadMini='35', iPad9p7='35', iPad='35', iPadAir='35', iPad11='35', iPad12p9='40', Nexus1='20', NexusR='25', Nexus7R='30', Pixel2R='25', Pixel3R='25', GalaxyS8='25', Nexus6P='25', Pixel3XL='25', PixelC='40'}" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Padding="10,5" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4" Text="{Binding FactionName}" HorizontalOptions="Start" VerticalTextAlignment="End" FontAttributes="Bold"
FontSize="{markups:OnScreenSize DefaultSize='12', iPod='15', iPhoneSE='15', iPhoneXR='18', iPhoneX='19', iPhone13='19', iPhone7p='19', iPhone11pm='19', iPhone13pm='16',
iPadMini='30', iPad9p7='30', iPad='32', iPadAir='32', iPad11='34', iPad12p9='34', Nexus1='14', NexusR='14', Nexus7R='22', Pixel2R='20', Pixel3R='20', GalaxyS8='20', Nexus6P='18', Pixel3XL='18', PixelC='34'}" />
<Label Padding="0,5" Grid.Row="0" Grid.Column="4" Grid.ColumnSpan="2" Text="{Binding NumberMembersString}" HorizontalOptions="Center" VerticalTextAlignment="End" FontAttributes="Bold"
FontSize="{markups:OnScreenSize DefaultSize='12', iPod='15', iPhoneSE='15', iPhoneXR='18', iPhoneX='19', iPhone13='19', iPhone7p='19', iPhone11pm='19', iPhone13pm='16',
iPadMini='30', iPad9p7='30', iPad='32', iPadAir='32', iPad11='34', iPad12p9='34', Nexus1='14', NexusR='14', Nexus7R='22', Pixel2R='20', Pixel3R='20', GalaxyS8='20', Nexus6P='18', Pixel3XL='18', PixelC='34'}"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal"></VisualState>
<VisualState Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor" Value="#ae00ff"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Relevant code from the ViewModel:
public Command<Faction> ItemTapped { get; }
public FactionTopPageViewModel()
{
ItemTapped = new Command<Faction>(OnItemSelected);
}
private void OnItemSelected(Faction faction)
{
if (faction == null)
{
SelectedItem = null;
DisableFactionButtons();
return;
}
EnableFactionButtons();
SelectedItem = faction;
}
This results in our buttons enabled at the bottom of the page, but the faction (essentially a team) is not being highlighted in the CollectionView, so the user does not receive confirmation of selecting the proper faction.
If I remove the tapgesture and work through the CollectionView commands setting the SelectionMode="Single", SelectionChangedCommand={Binding IsTapped}, and SelectionChangedCommandParameter={Binding .} then the selected Faction highlights without enabling any buttons. These issues are not platform-specific, like the ListView ViewCell background.
I have been working on this longer than I care to mention, as it seems like I have not wrapped my head around some relatively simple concept. Any help would be greatly appreciated, this issue is holding up the next release of our app.

Expander Handler Issue? System.Exception: 'Handler not found for view Xamarin.CommunityToolkit.UI.Views.Expander.'

I'm using Visual Studio 2022 preview 2.0 MAUI. I want to used a expander in MAUI, I have used Xamarin.CommunityToolkit.MauiCompat nuget. But I am seeing the exception System.Exception: 'Handler not found for view Xamarin.CommunityToolkit.UI.Views.Expander. How can I resolve this issue in MAUI.
My UI is:
<behaviors:Expander>
<behaviors:Expander.Header>
<HorizontalStackLayout Margin="33,-10,22,10">
<Label FontAttributes="Bold" WidthRequest="230" VerticalOptions="Center" Text="Monday" TextColor="{DynamicResource Black}" FontSize="{DynamicResource AppFontSize_Default}"></Label>
<Image Margin="0,0,30,0" Source="plus.png" HorizontalOptions="StartAndExpand" VerticalOptions="CenterAndExpand" WidthRequest="15" HeightRequest="20">
<Image.Triggers>
<DataTrigger TargetType="Image" Binding="{Binding Source={RelativeSource AncestorType={x:Type behaviors:Expander}}, Path=IsExpanded}" Value="True">
<Setter Property="Source" Value="plus.png" />
</DataTrigger>
</Image.Triggers>
</Image>
<RadioButton BackgroundColor="Transparent" BorderColor="{DynamicResource DefaultColor}"></RadioButton>
</HorizontalStackLayout>
</behaviors:Expander.Header>
<behaviors:Expander.ContentTemplate>
<DataTemplate>
<Label Text="{Binding CustomerNotes}" HorizontalOptions="StartAndExpand" TextColor="Black" FontSize="14" Padding="10,0,0,0"></Label>
</DataTemplate>
</behaviors:Expander.ContentTemplate>
</behaviors:Expander>
I have downloaded the nuget:
Xamarin.CommunityToolkit.MauiCompat
Xamarin.CommunityToolkit.Markup.MauiCompat
Also I have add handler on my MauiProgram.cs page
// Register ALL handlers in the Xamarin Community Toolkit assembly
handlers.AddCompatibilityRenderers(typeof(Xamarin.CommunityToolkit.UI.Views.MediaElementRenderer).Assembly);
// Register just one handler for the control you need
handlers.AddCompatibilityRenderer(typeof(Xamarin.CommunityToolkit.UI.Views.MediaElement), typeof(Xamarin.CommunityToolkit.UI.Views.MediaElementRenderer));
I'm not sure how well the Xamarin Forms Community Toolkit works with MAUI. The Maui Community Toolkit is still in pre-release, but they have plans to add the Expander Control.
You can track the Expander proposal issue on Github.

Xamarin's forms Date Picker android icon a bit out of way

I am trying to place a synfcusion button that has a calendar image near a xarmain forms entry box.
But its a bit out of alignment what I have tried so far is.
<Label Text="Please select a start date below"></Label>
<StackLayout Orientation="Horizontal">
<Entry x:Name="txtDateStartEntry" WidthRequest="200" ></Entry>
<syncfusion:SfButton x:Name="btnPickStartDate" CornerRadius="10" HorizontalTextAlignment="Start" ShowIcon="True" Clicked="btnPickStartDate_Clicked" FontSize="24" BorderThickness="2" TextColor="White" BackgroundColor="White" Text="..." >
<syncfusion:SfButton.Content>
<Grid ColumnDefinitions="Auto, *, Auto" ColumnSpacing="16" Padding="16">
<Image Grid.Column="1" HorizontalOptions="End" WidthRequest="30" HeightRequest="30" Source="cal16.png" VerticalOptions="End"/>
</Grid>
</syncfusion:SfButton.Content>
</syncfusion:SfButton>
</StackLayout>
What I have eneded up with is this.
As you can see its a bit far away from the entry field and doesnt look like it belongs.
If you're using Syncfusion, you should make use of SfTextInputLayout which provides leading/trailing view functionality for the express purpose of adding descriptive iconography to an input view.
Code example assumes importing the following xmlns:
xmlns:sftl="clr-namespace:Syncfusion.XForms.TextInputLayout;assembly=Syncfusion.Core.XForms"
<sftl:SfTextInputLayout TrailingViewPosition="Inside">
<Entry x:Name="txtDateStartEntry" WidthRequest="200" />
<sftl:SfTextInputLayout.TrailingView>
<Image HeightRequest="30" Source="cal16.png">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="btnPickStartDate_Clicked" />
</Image.GestureRecognizers>
</Image>
<sftl:SfTextInputLayout.TrailingView>
</sftl:SfTextInputLayout>
Note: when using LeadingView or TrailingView, it's recommended to not assign a Width value as Syncfusion will calculate the width based on the height you request to maintain aspect ratio of the specified view. Therefore I have intentionally excluded HeightRequest from the Image.

Drag and Drop on Xamarin Forms

We want to implement drag and drop functionality in Xamarin forms
and in this user should be able to drag an emoji from 1 place, and put on another. We don’t want the source emoji to go away though and should be able to come to know on which employee, rating is given .
Image how it is before
Image how it is after
Question also posted on:
https://forums.xamarin.com/discussion/184104/drag-and-drop-on-xamarin-forms/p1?new=1
We have checked a few links like below, but none of them seem to work:
Xamarin Forms Drag Image between Views
https://blog.francois.raminosona.com/drag-and-drop-in-xamarin-forms/
Will appreciate if could get some tips on how to do it and even if this was possible on forms?
You could check the code below.
xaml:
<StackLayout Margin="10">
<StackLayout Margin="10" Orientation="Horizontal">
<components:DragAndDropSample3ReceivingView
BackgroundColor="Beige"
HeightRequest="80"
WidthRequest="80" />
<components:DragAndDropSample3ReceivingView
BackgroundColor="Beige"
HeightRequest="80"
WidthRequest="80" />
<components:DragAndDropSample3ReceivingView
BackgroundColor="Beige"
HeightRequest="80"
WidthRequest="80" />
</StackLayout>
<BoxView
BackgroundColor="Blue"
HeightRequest="5"
WidthRequest="3" />
<StackLayout Margin="10" Orientation="Horizontal">
<components:DragAndDropSample3MovingView
BackgroundColor="Red"
CornerRadius="40"
HeightRequest="40"
WidthRequest="40" />
<components:DragAndDropSample3MovingView
BackgroundColor="Green"
CornerRadius="40"
HeightRequest="40"
WidthRequest="40" />
</StackLayout>
</StackLayout>
Code Behind:
public void OnDropReceived(IDragAndDropMovingView view)
{
if (view is DragAndDropSample3MovingView sender)
{
var control = new DragAndDropSample3MovingView()
{
BackgroundColor=sender.BackgroundColor,
CornerRadius=sender.CornerRadius,
WidthRequest=sender.WidthRequest,
HeightRequest=sender.HeightRequest,
};
Content = control;
}
}
Screenshot:
You could check the source file from the code project for reference.
https://github.com/WendyZang/Test/tree/master/Drag_Drop_Controls/Xamarin-Developer-Sample-master

Xamarin Forms ToolbarItem doesn't change IsEnabled from XAML

I'm facing a problem with ToolbarItem and IsEnabled property when trying to turn it on/off from XAML using triggers. ToolbarItem doesn't support triggers, so what I do is to create a Button (a hidden one) which supports triggers and then bind Button.IsEnabled to ToolbarItem.IsEnabled; here is the sample code:
<ContentPage.ToolbarItems>
<ToolbarItem x:Name="tlbSave" Text="Save" Clicked="Handle_Clicked">
<ToolbarItem.IsEnabled>
<Binding Source="{x:Reference btnTest}" Path="IsEnabled" />
</ToolbarItem.IsEnabled>
</ToolbarItem>
</ContentPage.ToolbarItems>
<ContentPage.Content>
<StackLayout Padding="10" VerticalOptions="CenterAndExpand">
<Entry x:Name="txtTest" HorizontalOptions="FillAndExpand" />
<Button x:Name="btnTest" Text="HIDDEN" IsEnabled="false" HorizontalOptions="FillAndExpand">
<Button.Triggers>
<MultiTrigger TargetType="Button">
<MultiTrigger.Conditions>
<BindingCondition Binding="{Binding Source={x:Reference txtTest}, Path=Text.Length,
Converter={convert:IsPositiveIntegerConverter}}" Value="true" />
</MultiTrigger.Conditions>
<Setter Property="IsEnabled" Value="True" />
</MultiTrigger>
</Button.Triggers>
</Button>
</StackLayout>
</ContentPage.Content>
If you try this piece of code you will see how btnTest gets enable/disable when txtTest.Text has some value. But it isn't affecting tlbSave.IsEnabled property.
However, this work perfect in code behind when I set tlbSave.IsEnabled into btnText.PropertyChanged EventHandler
btnTest.IsVisible is false, I'm just showing it up for testing purposes.
Any idea about how to deal with this?
This is because of the IsEnabled property of ToolbarItem is read-only.
If you just set IsEnabled property of a toolbar item in your XAML to false or true, you will get the following exception at runtime.
System.InvalidOperationException: The BindableProperty "IsEnabled" is readonly.
And if you take a look at Microsoft's documentation, you will notice that you cannot directly set IsEnabled property of a toolbar item.
For disabling a toolbar item, the suggested way is to use a command and it's CanExecute.
I found out a way to solve this problem, at least a way better than implementing OnPropertyChange for btnTest
<ContentPage.ToolbarItems>
<ToolbarItem x:Name="tlbSave" Text="Save" Clicked="Handle_Clicked" />
</ContentPage.ToolbarItems>
<ContentPage.Content>
<StackLayout Padding="10" VerticalOptions="CenterAndExpand">
<Entry x:Name="txtTest" HorizontalOptions="FillAndExpand" />
<Button x:Name="btnTest" Text="HIDDEN">
<Button.Triggers>
<MultiTrigger TargetType="Button">
<MultiTrigger.Conditions>
<BindingCondition Binding="{Binding Source={x:Reference txtTest}, Path=Text.Length,
Converter={convert:IsPositiveIntegerConverter}}" Value="true" />
</MultiTrigger.Conditions>
<Setter Property="IsEnabled" Value="True" />
</MultiTrigger>
</Button.Triggers>
<Button.IsEnabled>
<Binding Source="{x:Reference tlbSave}" Path="IsEnabled" Mode="OneWayToSource" />
</Button.IsEnabled>
</Button>
</StackLayout>
</ContentPage.Content>
Then set btnTest.IsEnabled = false; inside constructor and everything will go as smooth as I want.

Resources