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

时间:2014-07-08 11:36:28

标签: xamarin.forms

有一些关于如何通过 -

创建“自定义控件”的好例子

我想创建一个“复合自定义控件OR usercontrol ”,它包含在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>

代码隐藏 -

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

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

为该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 ().???
            }
        }
    }
}

只是不能让各个部分一起工作,ContentView似乎在页面上渲染得很好,但无法解决如何在viewrenderer中访问其Child Native控件。

还要展示如何使用Binding作为标签和条目文本值。

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

1 个答案:

答案 0 :(得分:2)

这是你的意思吗?

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

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

        public Label Label
        {
            get
            {
                return MyLabel;
            }
            set
            {
                MyLabel = value;
            }
        }

        public Entry Entry
        {
            get
            {
                return MyEntry;
            }
            set
            {
                MyEntry = value;
            }
        }
    }

渲染器中的一些魔法来自定义页面上的控件:

[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;
                newsContentView.Label.Text = "It´s some kind of..";
                newsContentView.Entry.Text = "MAGIC!";
                newsContentView.Entry.BackgroundColor = Color.Blue;
                newsContentView.Entry.RotationX = 180;
                newsContentView.Entry.Focus();

            }
        }
    }
}

编辑:

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

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

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

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

            if (newModel != null) {
                LinearLayout layout = new LinearLayout (Application.Context);
                layout.Orientation = Orientation.Vertical;

                TextView tv = new TextView (Application.Context);
                tv.Ellipsize = TextUtils.TruncateAt.Middle;
                tv.Text = "It´s some kind of..";

                EditText et = new EditText (Application.Context);
                et.SetTextColor (Graphics.Color.Chocolate);
                et.Text = "MAGIC!";

                layout.AddView (tv);
                layout.AddView (et);

                SetNativeControl (layout);
            }
        }
    }
}

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