为了能够创建需要在 Xamarin 环境中本地完成的样式,我使用了自定义渲染器。在 android 端,我收到一个 System.InvalidCastException ,我不知道如何解决这个问题。由于 this guys 对我之前遇到的错误的建议(没有默认构造函数接受 0 个参数错误),我目前正在包装 Android.Widget.StackView。该错误似乎不是由于声明或实例化而发生的,而是当我将它添加到 ContentView 并在返回时发生(通过注释掉如下所示的行找到)。

        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
                }
            }
        };

代码

渲染器 View

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)
        {
        }
    }
}

错误堆栈跟踪

最佳答案

不确定这是否真的是您问题的根源,但如果不是,它肯定会在事后给您带来问题。

在您的 RendererView 中,您的所有绑定(bind)属性都应将其 declaringType 设置为声明它们的类,即 RendererView

例如,您的第一个绑定(bind)属性应如下所示:

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

然后对所有其他人做同样的事情。如果那不能解决它,一定要告诉我。

编辑:根据下面 OP 的评论,初始错误来自 ExportRenderer 行,它需要像这样声明 RendererView 而不是 stackViewWrapper:
[assembly: ExportRenderer(typeof(Project.RendererView), typeof(RendererViewAndroid))]

10-08 02:23