ListView Localization

SiliconMonkeySiliconMonkey CAMember ✭✭
edited January 2018 in Xamarin.Forms

I have been localizing a Xamarin Forms app at work. It has been going exceedingly well and localizing with the RESX files is smooth and simple...

until I got to the one and only ListView in the app

The app has menu options to change the language on-the-fly. We are not relying on the culture info setting of the device. Localization is within the app only.

Example:
To assign localized button text I would use the button's x:Name and assign the resource
ie: HelloButton.Text = AppResource.HelloButtonText

I wanted to iterate through the ListView and change all the button, label and placeholder text to the current language on-the-fly. This is what I wanted to do:

foreach(var item in MyListView.Items)
{
Button helloButton = item.FindByName("HelloButton");
helloButton.Text = AppResource.HelloButtonText;
}

I read ListView doesn't implement IEnumerable or ICollection so the Items property does not exist.
So how to loop through a ListView to change all the buttons label text?

(Currently looking at a DataTemplateSelector class to build both a French and English data template and swap it out programmatically, but I'd rather not if there is another way)

Answers

  • NMackayNMackay GBInsider, University mod
    edited January 2018
  • SiliconMonkeySiliconMonkey CAMember ✭✭
    edited January 2018

    Thanks @NMackay but the ItemsSource property only gives me access to the ListView's data. I'm trying to get at some of the ancillary controls in each item. For example, you might see this in the ListView's DataTemplate to define a field (both a label and it's data)

    <StackLayout Orientation="Horizontal"> <Label x:Name="NameLabel" Text="Name: " /> <Label x:Name="NameData" Text="{Binding Name}" /> </StackLayout>

    You can certainly loop through the ItemsSource and gain access to the bound data but how do I get at the "NameLabel" Label? For example, I click on a "Spanish" button somewhere on the page. This should change the Text attribute in every "NameLabel" in the ListView from "Name:" to "Nombre:"

  • SiliconMonkeySiliconMonkey CAMember ✭✭
    edited January 2018

    Here's a better example. How do I get to the "NameLabel" Label programmatically?

            <ListView x:Name="MyListView" >
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Orientation="Horizontal">
                                <Label x:Name="NameLabel" Text="Name: " />
                                <Label x:Name="NameField" Text="{Binding .}"  />
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
    

  • SiliconMonkeySiliconMonkey CAMember ✭✭
    edited January 2018

    For those that follow that experience this issue, I did solve this although in a hacky way.

    The ListView was setup just like an MS Access continuous entry form. This is OK in the ASP.NET and I believe WPF's ListView control but not Xamarin's version of it.

    You can't get to the ancillary controls of the ListView items, only the data that is bound to the ListView.ItemsSource. In order to set the button, label and placeholder text in each ListViewItem I had to add bindable properties to the data for each of the ancillary control labels and then bind these properties to the Text, Title and Placeholder properties of the ancillary controls.

    When the user changes the language on the fly, I could then iterate through the data and reassign the label text to the chosen language.

  • ish1313ish1313 Member ✭✭

    was googling on related issue and found this thread .
    why you just don't use ?

    [ContentProperty("Text")]
    public class TranslateExtension : IMarkupExtension

    …..
    xmlns:i18n ="clr-namespace:AppName; assembly = AppName"
    …...

                    <Label Text="{i18n:Translate Weight}" Grid.Row="1"  />
                      <Label Text="{Binding Weight}" Grid.Row="1" Grid.Column="1"/>
                                                                                 </Grid>
                                                            </ViewCell>
                        </DataTemplate>
                    </ListView.ItemTemplate>
    
Sign In or Register to comment.