2

I am trying to create a custom control in Xamarin.Forms and expose a property correctly. I'm sure the same principals apply to WPF

My Control

public class ExtendedMap : Map
{
    public ExtendedMap()
    {

    }

    private IList<Pin> _staticPins;
    public IList<Pin> StaticPins
    {
        get { return _staticPins; }
        set { _staticPins = value;}
    }
}

And in Xaml I am currently using it like so:

<custom:ExtendedMap x:Name="map" Grid.Row="2" HorizontalOptions="Fill" VerticalOptions="Fill" IsVisible="{Binding CustomerSearchControlViewModel.MapIsDisplayed}">
  <custom:ExtendedMap.StaticPins>
    <x:Array Type="{x:Type maps:Pin}">
      <maps:Pin Label="Hello" Address="{Binding CustomerSearchControlViewModel.SelectedCustomer.Address, Converter={StaticResource AddressToStringConverter}" Position="{Binding CustomerSearchControlViewModel.SelectedCustomer.Position}" Type="Place"/>
    </x:Array>
  </custom:ExtendedMap.StaticPins>
</custom:ExtendedMap>

If I take the <x:Array> part out I get an error:

Sequence is not IEnumerable

but I would like to use it like:

<custom:ExtendedMap.StaticPins>
      <maps:Pin Label="Hello" Address="{Binding CustomerSearchControlViewModel.SelectedCustomer.Address, Converter={StaticResource AddressToStringConverter}" Position="{Binding CustomerSearchControlViewModel.SelectedCustomer.Position}" Type="Place"/>
 </custom:ExtendedMap.StaticPins>

Is this possible? What is the correct way to do this?

JKennedy
  • 18,150
  • 17
  • 114
  • 198
  • take a look at `IList Interface` https://msdn.microsoft.com/en-us/library/bb335435(v=vs.110).aspx – MethodMan Nov 09 '15 at 17:01
  • @MethodMan Thanks but I'm not sure where I'm supposed to be looking? – JKennedy Nov 09 '15 at 17:02
  • what do you mean.. I just gave you the link.. sounds like you have an `IEnumerable` issue going on.. – MethodMan Nov 09 '15 at 17:05
  • @MethodMan I mean I can see the Enumerable API documentation but I don't understand how that links/solves my issue? Sorry if I'm missing something – JKennedy Nov 09 '15 at 17:07
  • well look at this solution here then https://forums.xamarin.com/discussion/55473/is-it-possible-to-use-xamarin-maps-to-add-map-pins-in-xaml – MethodMan Nov 09 '15 at 17:09
  • @MethodMan: is that second link just this exact question? I.e. it looks to me like the OP here also posted the messages on that other page. – Peter Duniho Nov 09 '15 at 19:28
  • @PeterDuniho well spotted. That is the exact same question on another forum – JKennedy Nov 10 '15 at 08:37

2 Answers2

1

From What is the worst gotcha in WPF?

3) Property's type must implement IList, not IList<T>, if the property is to be recognized by XAML as a collection property.

More generally, XAML and generic types don't work very well together, unfortunately.

If that does not address your concern, please improve your question. Provide a good, minimal, complete code example that reliably reproduces the problem, so that it is more clear what the scenario is.

You may also be interested in How Can I Nest Custom XAML Elements?, which shows how you can declare a property as the default collection for child elements in XAML.

Community
  • 1
  • 1
Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • Your first point was spot on. I had to Implement `IList` not `IList`. I will post my actual solution later. – JKennedy Nov 10 '15 at 09:07
0

Thanks to @Peter Duniho's answer it forced me in the right direction. It was a combination of the points he mentioned.

Firstly I had to implement IList on my ExtendedMap so that I could set the List of items in Xaml without using an Array

The final solution looked like so:

public class ExtendedMap : Map : IList
{
    public ExtendedMap()
    {

    }

    private IList<Pin> _staticPins = new List<Pin>();
    public IList<Pin> StaticPins
    {
        get { return _staticPins; }
        set { _staticPins = value;}
    }

    //..IList Implementations

    Public int Add(object item)
    {
       var pin = (Pin)item;
       StaticPins.Add(pin);
       return 1;
    }
}
JKennedy
  • 18,150
  • 17
  • 114
  • 198
  • I assume that you chose to implement `IList` in the class itself, rather than adding `[ContentProperty("StaticPins")]` to the declaration, because the former approach allows you to preserve the generic `IList` on the property type while the latter would not. If that's true, you might want to add a comment to your answer above to make that clear to future readers, so that they can understand better the trade-offs between the two options. – Peter Duniho Nov 10 '15 at 16:42