Xamarin.Forms UserControl使用XAML和自定义渲染器

Wic*_*edW 7 xamarin.forms

已经有一些关于如何创建"自定义控件"的好例子 -

我想创建一个"复合自定义控件或用户控件 ",它包含在XAML中定义的多个元素(在共享代码中),然后使用渲染器进行自定义(比如调整每个平台的样式).

有没有人有这样做的例子呢?具有可绑定标签和输入框的视图的简单示例应足以显示主要原则.

这是我到目前为止 -

定义了一个ContentView来表示我们的用户控件布局和内容.

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="News.Forms.VisualNewsContentView">
    <ContentView.Content>
        <StackLayout>
            <Label x:Name="MyLabel" Text="Label"></Label>
            <Entry x:Name="MyEntry" Text="Entry"></Entry>
        </StackLayout>
    </ContentView.Content>
</ContentView>
Run Code Online (Sandbox Code Playgroud)

代码隐藏 -

public partial class VisualNewsContentView : ContentView
{
    public VisualNewsContentView ()
    {
        InitializeComponent ();
    }

    // Not sure if I need this to access Entry ...
    public Entry GetEntry ()
    {
        return MyEntry;
    }
}
Run Code Online (Sandbox Code Playgroud)

为该ContentView添加Android自定义渲染器,如何访问和自定义ContentView的原生部件/控件?

[assembly:ExportRenderer (typeof(VisualNewsContentView), typeof(VisualNewsRenderer))]

namespace News.Forms.Android
{
    public class VisualNewsRenderer: ViewRenderer
    {
        public VisualNewsRenderer () { }

        protected override void OnModelChanged (VisualElement oldModel, VisualElement newModel)
        {
            base.OnModelChanged (oldModel, newModel);

            if (newModel != null) {
                VisualNewsContentView newsContentView = newModel as VisualNewsContentView;

                // i.e. How could I get hold of EditText etc so I could natively customise its appearance? When you use a built in renderer like EntryRenderer you can use Control to access native control.
                Console.WriteLine (newsContentView.GetLabel ().Text);
                EditText ed = (EditText)newsContentView.GetEntry ().???
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

只是无法将各个部分组合在一起工作,ContentView似乎在页面上呈现良好,但无法解决如何在viewrenderer中访问其Child Native控件.

很高兴还可以展示如何使用Binding作为Label和Entry Text值.

我不想为usercontrol的每个标签/条目等定义自定义渲染器.

bka*_*dol 2

这是你的意思吗?

\n\n

访问 Xamarin.Forms 控件的一些属性:

\n\n
    public partial class VisualNewsContentView : ContentView\n    {\n        public VisualNewsContentView()\n        {\n            InitializeComponent();\n        }\n\n        public Label Label\n        {\n            get\n            {\n                return MyLabel;\n            }\n            set\n            {\n                MyLabel = value;\n            }\n        }\n\n        public Entry Entry\n        {\n            get\n            {\n                return MyEntry;\n            }\n            set\n            {\n                MyEntry = value;\n            }\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

渲染器内部的一些魔法可以自定义页面上的控件:

\n\n
[assembly:ExportRenderer (typeof(VisualNewsContentView), typeof(VisualNewsRenderer))]\n\nnamespace News.Forms.Android\n{\n    public class VisualNewsRenderer: ViewRenderer\n    {\n        public VisualNewsRenderer () { }\n\n        protected override void OnModelChanged (VisualElement oldModel, VisualElement newModel)\n        {\n            base.OnModelChanged (oldModel, newModel);\n\n            if (newModel != null) {\n                VisualNewsContentView newsContentView = newModel as VisualNewsContentView;\n                newsContentView.Label.Text = "It\xc2\xb4s some kind of..";\n                newsContentView.Entry.Text = "MAGIC!";\n                newsContentView.Entry.BackgroundColor = Color.Blue;\n                newsContentView.Entry.RotationX = 180;\n                newsContentView.Entry.Focus();\n\n            }\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编辑:

\n\n

我不知道是否可以将您的控件从 XAML 页面映射到本机控件。您可以在渲染器中添加您想要本地自定义的控件。

\n\n
    [assembly:ExportRenderer (typeof(VisualNewsContentView), typeof(VisualNewsRenderer))]\n\nnamespace News.Forms.Android\n{\n    public class VisualNewsRenderer: NativeRenderer\n    {\n        public VisualNewsRenderer () { }\n\n        protected override void OnModelChanged (VisualElement oldModel, VisualElement newModel)\n        {\n            base.OnModelChanged (oldModel, newModel);\n\n            if (newModel != null) {\n                LinearLayout layout = new LinearLayout (Application.Context);\n                layout.Orientation = Orientation.Vertical;\n\n                TextView tv = new TextView (Application.Context);\n                tv.Ellipsize = TextUtils.TruncateAt.Middle;\n                tv.Text = "It\xc2\xb4s some kind of..";\n\n                EditText et = new EditText (Application.Context);\n                et.SetTextColor (Graphics.Color.Chocolate);\n                et.Text = "MAGIC!";\n\n                layout.AddView (tv);\n                layout.AddView (et);\n\n                SetNativeControl (layout);\n            }\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

但这样你就不会使用你的ContentView..对不起,我没有比这更好的了..

\n