Search code examples
xamarin.formsdata-bindingenumstypeconverter

Xamarin.Forms: Pass Enum Parameter to URL with Type Converter


In my page I have a Binding Property of enum type:

[QueryProperty(nameof(EnumProp), nameof(EnumProp))]
public partial class MyPage : ContentPage
{
    public static readonly BindableProperty EnumPropProperty =
       BindableProperty.Create(nameof(EnumProp), typeof(MyEnum), typeof(MyPage), propertyChanged: OnEnumPropChanged);

    public MyEnum EnumProp
    {
        get => (MyEnum)GetValue(EnumPropProperty);
        set => SetValue(EnumPropProperty, value);
    }

I would like to call this page by GoToAsync:

        MyEnum enumProp = MyEnum.ThisValue;
        string dest = $"{nameof(MyPage)}?{nameof(MyPage.EnumProp)}={enumProp}";
        await Shell.Current.GoToAsync(dest);

In my example, dest is "MyPage?EnumProp=ThisValue" and GoToAsync throws InvalidCastException.

So I added a TypeConverter to property EnumProp:

    [TypeConverter(typeof(StringToEnumConverter<MyEnum>))]
    public MyEnum EnumProp

First I implemented StringToEnumConverter<T> derived from Xamarin.Forms.TypeConverter then I implemented interface IValueConverter. In both cases InvalidCastException is thrown:

Edit: Stack Trace is as follows:

System.InvalidCastException
  HResult=0x80004002
  Nachricht = Invalid cast from 'System.String' to 'XXX.MyEnum'.
  Quelle = System.Private.CoreLib
  Stapelüberwachung:
   bei System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)
   bei Xamarin.Forms.ShellContent.ApplyQueryAttributes(Object content, IDictionary`2 query, IDictionary`2 oldQuery)
   bei Xamarin.Forms.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes)
   bei Xamarin.Forms.BindableObject.SetValue(BindableProperty property, Object value, Boolean fromStyle, Boolean checkAccess)
   bei Xamarin.Forms.ShellNavigationManager.ApplyQueryAttributes(Element element, IDictionary`2 query, Boolean isLastItem, Boolean isPopping)
   bei Xamarin.Forms.ShellSection.<GoToAsync>d__69.MoveNext()
   bei Xamarin.Forms.ShellNavigationManager.<GoToAsync>d__13.MoveNext()
   bei XXX.MyPage.<ToDetail>d__17.MoveNext() in C:\Users\MyUser\Development\...\PackObjectItem.cs: Zeile46

End Edit

What is to do in my case?


Solution

  • You can convert the data to a string type and pass it through.

    Please refer to the following code:

    [QueryProperty(nameof(EnumProp), nameof(EnumProp))]
    public partial class MyPage : ContentPage
    {
    
        public MyPage()
        {
            InitializeComponent();
        }
    
        public string EnumProp
        {
            set
            {
                LoadData(value);
            }
        }
    
        private void LoadData(string value)
        {
            System.Diagnostics.Debug.WriteLine("the passed data is " + value);
    
            Title = "---> "+value;
        }
     }
    

    Then you can pass data as follows:

      MyEnum enumProp = MyEnum.Spring;
    
     await Shell.Current.GoToAsync($"mypage?EnumProp={enumProp.ToString()}");  
    

    Note

    1.the string mypage is the route of page MyPage

            Routes.Add("mypage", typeof(MyPage));
    

    2.the code of MyEnum.cs is:

    public enum MyEnum
    {
        Spring,
        Summer,
        Autumn,
        Winter
    }