0
votes

I've read the examples and documentation on creating a shared image in the XAML/Shared Library project in Xamarin Forms, however, the examples don't show me how to bind to a list of shared images.

How should I go about binding a ListView with a DataTemplate to a whole bunch of images I have stored in the shared project?

1

1 Answers

0
votes

This is a bit tricky - the naming "conventions" for Embedded Resources are a bit odd, and if anything goes wrong, the output is usually something along the lines of "can't find image" or "your binding is wrong".

I was able to get this working through a combination of peeking at the WorkingWithImages code here and futzing around with creating the ListView in both C# and XAML.

First, here's what the binding model (the POCO class that the ListView is binding to) looks like:

        People = new List<PeopleSearchCell>();


        People.Add(new PeopleSearchCell
        {
            Name = "My Name",
            List = "Some string list",
            EmbeddedPhoto = ImageSource.FromResource("YOUR_ASSEMBLY_NAME_HERE.Folder1.Folder2.ACTUAL_IMAGE_NAME.jpeg", typeof(PeopleSearchPage).GetTypeInfo().Assembly)
        }) ;

        BindingContext = this;

Here's a working XAML example, from the PeopleSearchPage:

            <ListView ItemsSource="{Binding People}"
                  ItemSelected="OnListViewItemSelected"
                  ItemTapped="OnListViewItemTapped"
                  HasUnevenRows="True"
                  x:Name="PeopleList"
                  >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid Padding="10">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="*" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Image Grid.RowSpan="2"
                                   Grid.Column="0"
                               Source="{Binding EmbeddedPhoto}"
                               Aspect="AspectFill"
                                   HeightRequest="80"
                                   WidthRequest="80"
                                />
                            <Label Grid.Row="0"
                                Grid.Column="1"
                               Text="{Binding Name}"
                               FontAttributes="Bold"
                                   />
                            <Label Grid.Row="1"
                               Grid.Column="1"
                               Text="{Binding List}"
                               VerticalOptions="End" />
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

Alternatively, creating the ListView in C#:

        PeopleListView.ItemTemplate = new DataTemplate(() => 
        {
            ViewCell vc = new ViewCell();

            Grid vcGrid = new Grid();
            vcGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
            vcGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });

            vcGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Auto) });
            vcGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });

            var gridImg = new Image();
            gridImg.SetBinding(Image.SourceProperty, "EmbeddedPhoto");
            gridImg.HeightRequest = 80;
            gridImg.WidthRequest = 80;
            gridImg.Aspect = Aspect.AspectFill;

            vcGrid.Children.Add(gridImg, 0, 0);
            Grid.SetRowSpan(gridImg, 2);

            var nameLabel = new Label();
            nameLabel.SetBinding(Label.TextProperty, "Name");
            nameLabel.FontAttributes = FontAttributes.Bold;

            vcGrid.Children.Add(nameLabel, 1, 0);

            var clientsLabel = new Label();
            clientsLabel.SetBinding(Label.TextProperty, "List");
            clientsLabel.VerticalOptions = new LayoutOptions(LayoutAlignment.End, false);

            vcGrid.Children.Add(nameLabel, 1, 1);

            vc.View = vcGrid;

            return vc;
        });