4

In order to be able to create a styling that needs to be done natively in the Xamarin environment, I am using a custom renderer. On the android side, I am receiving an System.InvalidCastException, and I do not know how to fix this issue. I am currently wrapping an Android.Widget.StackView due to this guys suggestion on a previous error I was getting (no default constructor takes 0 arguments error). The error does not seem to happen due to declaration or instantiation, but rather when I add it to the ContentView and happens at the return (found by commenting out the line as shown below).

        MainPage = new ContentPage {
            Content = new StackLayout {
                VerticalOptions = LayoutOptions.Center,
                Children = {
                    item1,
                    item2,
                    item3,
                    item4,
                    item5,
                    item6,
                    //rendererIWantToAdd,//taking out this line make it work. adding it breaks it
                }
            }
        };

Code

RendererView

public class RendererView :  View
{

    public static readonly BindableProperty ImageProperty = BindableProperty.Create(
        propertyName: "Src",
        returnType: typeof(string),
        declaringType: typeof(string),
        defaultValue: ""
    );
    public String Src
    {
        get { return (string)GetValue(ImageProperty); }
        set { SetValue(ImageProperty, value); }
    }

    public static readonly BindableProperty TextProperty = BindableProperty.Create(
        propertyName: "Text",
        returnType: typeof(string),
        declaringType: typeof(string),
        defaultValue: "Hello World"
    );
    public String Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    public static readonly BindableProperty ColorProperty = BindableProperty.Create(
        propertyName: "Color",
        returnType: typeof(string),
        declaringType: typeof(string),
        defaultValue: "#AAAAAA"
    );
    public String Color
    {
        get { return (string) GetValue(ColorProperty); }
        set { SetValue(ColorProperty, value); }
    }
}

RendererViewAndroid

[assembly: ExportRenderer(typeof(Project.RendererView), typeof(stackViewWrapper))]
namespace Project.Droid
{
    public class RendererViewAndroid : ViewRenderer<RendererView, stackViewWrapper>
    {

        Android.Widget.TextView label;
        Android.Widget.ImageView image;

        protected override void OnElementChanged(ElementChangedEventArgs<RendererView> e)
        {
            base.OnElementChanged(e);
            if (Control == null)
            {
                createItem(e);
            }

            if (e.OldElement != null)
            {

                unsubscribe(e);
            }

            if (e.NewElement != null)
            {
                subscribe(e);
            }



        }


        protected void createItem(ElementChangedEventArgs<RendererView> e)
        {


            SetNativeControl(new stackViewWrapper());
            label = new Android.Widget.TextView(Context)
            {
                Text = Element.Text
            };

            image = new Android.Widget.ImageView(Context);
            if (!string.IsNullOrWhiteSpace(Element.Src))
            {
                Context.Resources.GetBitmapAsync(Element.Src).ContinueWith((t) =>
                {
                    var bitmap = t.Result;
                    if (bitmap != null)
                    {
                        image.SetImageBitmap(bitmap);
                        bitmap.Dispose();
                    }
                }, TaskScheduler.FromCurrentSynchronizationContext());

            }
            else {
            //  // clear the image
                image.SetImageBitmap(null);
            }


            Control.AddView(image);
            Control.AddView(label);



        }
        protected void subscribe(ElementChangedEventArgs<RendererView> e)
        {

        }
        protected void unsubscribe(ElementChangedEventArgs<RendererView> e)
        {

        }





        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);
        }





    }


    public  class stackViewWrapper : Android.Views.View
    {
        public stackViewWrapper() : base(Android.App.Application.Context)
        {
        }
    }
}

Error Stack Trace

System.InvalidCastException: Specified cast is not valid. at at (wrapper castclass) System.Object:__castclass_with_cache (object,intptr,intptr) at Xamarin.Forms.Registrar1[TRegistrable].GetHandler (System.Type type) [0x0001b] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Core\Registrar.cs:24 at Xamarin.Forms.Registrar1[TRegistrable].GetHandler[TOut] (System.Type type) [0x00000] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Core\Registrar.cs:29 at Xamarin.Forms.Platform.Android.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x00006] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\Platform.cs:281 at Xamarin.Forms.Platform.Android.VisualElementPackager.AddChild (Xamarin.Forms.VisualElement view, IVisualElementRenderer oldRenderer, Xamarin.Forms.Platform.Android.RendererPool pool, Boolean sameChildren) [0x00023] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\VisualElementPackager.cs:72 at Xamarin.Forms.Platform.Android.VisualElementPackager.SetElement (Xamarin.Forms.VisualElement oldElement, Xamarin.Forms.VisualElement newElement) [0x00104] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\VisualElementPackager.cs:204 at Xamarin.Forms.Platform.Android.VisualElementPackager.Load () [0x00000] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\VisualElementPackager.cs:56 at Xamarin.Forms.Platform.Android.VisualElementRenderer1[TElement].SetPackager (Xamarin.Forms.Platform.Android.VisualElementPackager packager) [0x00007] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:327 at Xamarin.Forms.Platform.Android.VisualElementRenderer1[TElement].SetElement (Xamarin.Forms.Platform.Android.TElement element) [0x00111] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:195 at Xamarin.Forms.Platform.Android.VisualElementRenderer1[TElement].Xamarin.Forms.Platform.Android.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00027] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:128 at Xamarin.Forms.Platform.Android.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x0001f] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\Platform.cs:282 at Xamarin.Forms.Platform.Android.VisualElementPackager.AddChild (Xamarin.Forms.VisualElement view, IVisualElementRenderer oldRenderer, Xamarin.Forms.Platform.Android.RendererPool pool, Boolean sameChildren) [0x00023] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\VisualElementPackager.cs:72 at Xamarin.Forms.Platform.Android.VisualElementPackager.SetElement (Xamarin.Forms.VisualElement oldElement, Xamarin.Forms.VisualElement newElement) [0x00104] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\VisualElementPackager.cs:204 at Xamarin.Forms.Platform.Android.VisualElementPackager.Load () [0x00000] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\VisualElementPackager.cs:56 at Xamarin.Forms.Platform.Android.VisualElementRenderer1[TElement].SetPackager (Xamarin.Forms.Platform.Android.VisualElementPackager packager) [0x00007] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:327 at Xamarin.Forms.Platform.Android.VisualElementRenderer1[TElement].SetElement (Xamarin.Forms.Platform.Android.TElement element) [0x00111] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:195 at Xamarin.Forms.Platform.Android.VisualElementRenderer1[TElement].Xamarin.Forms.Platform.Android.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00027] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\VisualElementRenderer.cs:128 at Xamarin.Forms.Platform.Android.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x0001f] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\Platform.cs:282 at Xamarin.Forms.Platform.Android.Platform.AddChild (Xamarin.Forms.VisualElement view, Boolean layout) [0x00015] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\Platform.cs:518 at Xamarin.Forms.Platform.Android.Platform.SetPage (Xamarin.Forms.Page newRoot) [0x00089] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\Platform.cs:406 at Xamarin.Forms.Platform.Android.FormsApplicationActivity.InternalSetPage (Xamarin.Forms.Page page) [0x000b7] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\FormsApplicationActivity.cs:286 at Xamarin.Forms.Platform.Android.FormsApplicationActivity.SetMainPage () [0x00000] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\FormsApplicationActivity.cs:305 at Xamarin.Forms.Platform.Android.FormsApplicationActivity.LoadApplication (Xamarin.Forms.Application application) [0x0002d] in C:\BuildAgent2\work\aad494dc9bc9783\Xamarin.Forms.Platform.Android\FormsApplicationActivity.cs:108 at Project.Droid.MainActivity.OnCreate (Android.OS.Bundle bundle) [0x000ae] in /Users/ryan/project-app-xamarin/Project/Project.Droid/MainActivity.cs:47 at Android.App.Activity.n_OnCreate_Landroid_os_Bundle_ (IntPtr jnienv, IntPtr native__this, IntPtr native_savedInstanceState) [0x00011] in /Users/builder/data/lanes/3340/4e275588/source/monodroid/src/Mono.Android/platforms/android-23/src/generated/Android.App.Activity.cs:2426 at at (wrapper dynamic-method) System.Object:688deba4-7150-4f17-9062-10e53a94164c (intptr,intptr,intptr)

Brandon Minnick
  • 13,342
  • 15
  • 65
  • 123
R293
  • 53
  • 6

1 Answers1

1

Not sure if this is actually the root of your issue but it will certainly cause you problems afterwards if it is not.

In your RendererView all of your binding properties should have their declaringType set to the class that they are being declared in, which would be RendererView.

For example your first binding property should look like:

public static readonly BindableProperty ImageProperty = BindableProperty.Create(
    propertyName: "Src",
    returnType: typeof(string),
    declaringType: typeof(RendererView),
    defaultValue: ""
);

Then do the same for all the rest. If that doesn't fix it, definitely let me know.

Edit: According to the OP's comment below, the initial error came from the ExportRenderer line, which needed to declare the RendererView instead of the stackViewWrapper like so:

[assembly: ExportRenderer(typeof(Project.RendererView), typeof(RendererViewAndroid))]
hvaughan3
  • 10,955
  • 5
  • 56
  • 76
  • This unfortunately did not fix my error. I can definitely see how that would have caused me errors later on. What I am wondering is if the types that I am trying to use do not match up. For instance, I am using View with Android.Views.View. maybe they do not match up for renderers? Also, all of the code in my `createItem()` method has been commented out and it still errors out. That is all the info I have right now. – R293 Jun 21 '16 at 15:52
  • 1
    Your comment was almost on track. It was actually a different line though. In `RendererViewAndroid` The first shown line is actually the issues. The line should be `[assembly: ExportRenderer(typeof(Project.RendererView), typeof(**RendererViewAndroid**))]`, not type of wrapper. I will let you update your answer to make it the most complete (instead of making one myself) and I will mark that one right. Thank you very much! – R293 Jun 21 '16 at 18:05
  • @R293 Glad I could help a little. Edited my answer to include your answer as well. Thanks for commenting back with the actual answer to the issue. – hvaughan3 Jun 21 '16 at 19:10
  • Worst things that I always see is when the OP of any program error thread goes "lol jk got it" and never explains how. I would rather not be that. – R293 Jun 21 '16 at 19:26
  • @R293 Haha I completely agree – hvaughan3 Jun 21 '16 at 19:39