Define a collection inside XAML
Asked Answered
F

3

15

I want to create a Binding to a collection of strings defined inside XAML.

In WPF I could create an ArrayList as a resource with a key, ready to be used as the source of a Binding (using a StaticResource).

Is this possible in Xamarin Forms?

EDIT: I've tried with this XAML with the solution proposed by @Stephane Delcroix, but I'm getting an Unhandled Exception:

<?xml version="1.0" encoding="utf-8"?>

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:sys="clr-namespace:System;assembly=mscorlib"
             x:Class="ReferenceApp.Views.GamesPage"
             Title="Games">


    <ContentPage.Resources>
        <x:Array Type="{x:Type sys:String}" x:Key="array">
            <x:String>Hello</x:String>
            <x:String>World</x:String>
        </x:Array>
    </ContentPage.Resources>
    <Grid />

</ContentPage>

However, the exception is not thrown if I remove the <x:Array >... </x:Array>

What am I doing wrong?

Falange answered 3/10, 2016 at 16:50 Comment(3)
What control and which property of the control are you trying to bind your list to? I know how to do it for Picker.Items but not sure about a ListView.ItemSource for example.Zuber
I would like to use the ItemsSource of a ListViewFalange
You might still be able to work off the Picker example here.Zuber
W
10

I see that you are using the XF standard markup extensions. Your mistake seems to be in Type="{x:Type sys:String}", instead of sys:String you should write x:String which appears in the common xmlns:x

In this sample I fill a listview with strings

<ListView Margin="10">
    <ListView.ItemsSource>
        <x:Array Type="{x:Type x:String}">
            <x:String>Hello</x:String>
            <x:String>World</x:String>
        </x:Array>
    </ListView.ItemsSource>            
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <Label Text="{Binding}" />
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>                
</ListView>
Waugh answered 19/5, 2018 at 8:47 Comment(0)
L
7

You can use the built-in x:Array

<x:Array Type="{x:Type sys:String}" x:Key="array">
    <x:String>Hello</x:String>
    <x:String>World</x:String>
</x:Array>

with sys defined as xmlns:sys="clr-namespace:System;assembly=mscorlib"

or any collection you like, e.g. List

<scg:List x:TypeArguments="{x:Type sys:String}" x:Key="genericList">
    <x:String>Hello</x:String>
    <x:String>World</x:String>
</scg:List>

with sys defined as before, and scg being xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib"

Locarno answered 4/10, 2016 at 7:17 Comment(6)
I've tried it, but in Android I'm getting an Unhandled Exception. Please, see my edit in the OP.Falange
String is not defined in System.Runtime but in mscorlib if I'm not mistakenLocarno
Also, modifying questions usually makes the answer irrelevant, so please avoid doing that.Locarno
Sorry, but I don't know any other way to paste the XAML.Falange
BTW, I've modified the XAML with the xmlns poiting to mscorlib and it happens the same: I get an Unhandled Exception.Falange
this snippet was copy pasted from my unit tests of the XF xaml parser, so it should work. if it does not, please report a bugLocarno
A
0

This is an answer to the updated question.

<x:string> only supports constant values. You can address this issue with a Markup Extension

Its functionality is trivial: it returns its parameter.

using System;
using Xamarin.Forms.Xaml;

namespace YOURAPP.Extensions
{
    public class StringExtension : IMarkupExtension
    {
        public string Value { get; set; }

        public object ProvideValue(IServiceProvider serviceProvider)
        {
            return Value;
        }
    }
}

Use it like this in a view:

  1. Add xmlns:ext="clr-namespace:YOURAPP.Extensions" to the root element
  2. <ext:StringExtension Value="{anything here}" /> where you would otherwise want <x:string>

Note that this causes an Add to be called to the IEnumerable. For custom controls you would need initialization (to avoid a NullReferenceException) and and ObservableCollection to make sure that the view is updated on adding.

Acrobatic answered 30/9, 2021 at 14:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.