如何在Xamarin.Forms中为Listview标签的自动化id添加增量值?

如何在Xamarin.Forms中为Listview标签的自动化id添加增量值?,listview,xamarin,xamarin.forms,Listview,Xamarin,Xamarin.forms,我有这样的资源 <ContentPage.Resources> <ResourceDictionary> <x:String x:Key="LabelAutomationIdentifier">LBL_</x:String> </ResourceDictionary> </ContentPage.Resources> LBL_ 我的listview看起来像 <ListView I

我有这样的资源

<ContentPage.Resources>
    <ResourceDictionary>
        <x:String x:Key="LabelAutomationIdentifier">LBL_</x:String>
    </ResourceDictionary>
</ContentPage.Resources>

LBL_
我的listview看起来像

<ListView 
ItemsSource="{Binding ListItemSource}">
<ListView.ItemTemplate>
    <DataTemplate>
        <ViewCell>
            <Label 
                AutomationId="{StaticResource LabelAutomationIdentifier, StringFormat {0}_{Incremental Value OR UniqueIdentifier}'}"
                Text="{Binding Title}" />
        </ViewCell>
    </DataTemplate>
</ListView.ItemTemplate>


如何在自动化id中添加增量值

当你创建对象时,你不能创建吗???例如:
var\u id=0;
MenuItems=新的可观察集合
{
新菜单项
{
Id=_Id++;
Title=“xxxxxxxx”,
},
新菜单项
{
Id=_Id++;
Title=“yyyyyyy”,
},
新菜单项
{
Id=_Id++;
Title=“zzzzz”,
},
新菜单项
{
Id=_Id++;
Title=“jjj”,
},

};

我知道这很旧,但我最近也有同样的需求,找不到一个好的例子,所以我把它放在一起。如果有更好的方法,我很想看看:

首先,制作两个转换器:

public class RowNumberConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null || parameter == null)
        {
            return null;
        }
        int counter = 1;
        if (parameter is Binding && ((Binding)parameter).Source is ListView)
        {
            ListView localListView = (ListView)((Binding)parameter).Source;
            string listViewName = localListView.StyleId;
            foreach (var item in localListView.ItemsSource)
            {
                if (item.GetType() != value.GetType())
                {
                    return null;
                }

                if (item == value)
                {
                    return $"{listViewName}Row{counter}";
                }
                else
                {
                    counter++;
                }
            }
        }
        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
public class CellNameConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return $"{value}.{parameter}";
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
在您的XAML中:

使用其他名称空间引用在顶部引用转换器:

xmlns:converter="clr-namespace:THE NAMESPACE FOR YOUR CONVERTERS"
下面是一个示例列表视图:

<ListView x:Name="listViewResults" 
          AutomationId="listViewResults"
          Margin="0"                       
          IsPullToRefreshEnabled="True" 
          RefreshCommand="{Binding OnRefresh}"
          SelectionMode="None" 
          IsRefreshing="{Binding IsRefreshing}" 
          ItemsSource="{Binding Items}">
    <ListView.Resources>
        <converter:NullableIntConverter x:Key="NullableIntConverter"/>
        <converter:RowNumberConverter x:Key="RowNumberConverter"/>
        <converter:CellNameConverter x:Key="CellNameConverter"/>
    </ListView.Resources>
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout Margin="0,0,0,0" Orientation="Horizontal" HorizontalOptions="FillAndExpand">
                    <Grid Margin="5"
                          x:Name="listViewResultsRow"
                          AutomationId="listViewResultsRow">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="100" />
                            <ColumnDefinition Width="260" />
                            <ColumnDefinition Width="120" />
                            <ColumnDefinition Width="120" />
                            <ColumnDefinition Width="120" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*" />
                        </Grid.RowDefinitions>
                        <Label x:Name="listViewResultsRowNumber" Grid.Column="0" Text="{Binding Source={x:Reference listViewResultsRow}, Path=BindingContext, Converter={StaticResource RowNumberConverter}, ConverterParameter={Binding Source={x:Reference listViewResults}, Path=BindingContext}}" IsVisible="False"/>
                        <Label Grid.Row="0" 
                               Grid.Column="0" 
                               AutomationId="{Binding Source={x:Reference listViewResultsRowNumber}, Path=Text, Converter={StaticResource CellNameConverter},  ConverterParameter='Column1'}"     
                               Text="{Binding SampleId}" 
                               VerticalTextAlignment="Center" 
                               HorizontalOptions="Center" 
                               FontSize="Micro" />
                        <Label Grid.Row="0" 
                               Grid.Column="1" 
                               AutomationId="{Binding Source={x:Reference listViewResultsRowNumber}, Path=Text, Converter={StaticResource CellNameConverter},  ConverterParameter='Column2'}"     
                               Text="{Binding CancelReason}" 
                               VerticalTextAlignment="Center" 
                               HorizontalOptions="Center" 
                               FontSize="Micro" />
                        <Label Grid.Row="0" 
                               Grid.Column="2" 
                               AutomationId="{Binding Source={x:Reference listViewResultsRowNumber}, Path=Text, Converter={StaticResource CellNameConverter},  ConverterParameter='Column3'}"     
                               Text="{Binding DateCreated, StringFormat='{}{0:MM/dd/yyyy hh\\:mm:ss tt}'}" 
                               VerticalTextAlignment="Center" 
                               HorizontalOptions="Center"  
                               FontSize="Micro" />
                        <Label Grid.Row="0" 
                               Grid.Column="3" 
                               AutomationId="{Binding Source={x:Reference listViewResultsRowNumber}, Path=Text, Converter={StaticResource CellNameConverter},  ConverterParameter='Column4'}"     
                               Text="{Binding LastSyncAttempt, StringFormat='{}{0:MM/dd/yyyy hh\\:mm:ss tt}' }" 
                               VerticalTextAlignment="Center" 
                               HorizontalOptions="Center"  
                               FontSize="Micro" />
                        <Label Grid.Row="0" 
                               Grid.Column="4" 
                               AutomationId="{Binding Source={x:Reference listViewResultsRowNumber}, Path=Text, Converter={StaticResource CellNameConverter},  ConverterParameter='Column5'}"     
                               Text="{Binding DateSynced, StringFormat='{}{0:MM/dd/yyyy hh\\:mm:ss tt}' }" 
                               VerticalTextAlignment="Center" 
                               HorizontalOptions="Center"  
                               FontSize="Micro" />
                    </Grid>
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

这将为ListView中每一行中的每个单元格提供一个唯一的AutomationId,设置网格如下:

  • listViewResultsRow1.Column1
  • listViewResultsRow1.Column2
  • listViewResultsRow1.Column3
  • listViewResultsRow1.Column4
  • listViewResultsRow1.Column5
  • listViewResultsRow2.Column1
  • listViewResultsRow2.Column2

应该有办法做到这一点,因为xaml非常广泛和成熟。你能告诉我为什么我们可以这样做,什么是alernate解决方案吗?从目前的答案,我们需要绑定的数据,我不想这样做。