Xamarin.Forms中可重用的XAML控件

时间:2016-06-18 12:07:29

标签: c# xaml xamarin.forms

我写了一个很好的Grid以及其他一些控件,例如:EntryImage,现在我想以最简单的方式重复使用它。

这是我对Email财产的控制权:

<Grid
                Style="{StaticResource gridEntryStyle}">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="9*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="20" />
                    <RowDefinition Height="7" />
                    <RowDefinition Height="20" />
                </Grid.RowDefinitions>

                <controls:ExtendedEntry
                    Grid.Row="0"
                    Grid.Column="0"
                    Text="{Binding UserEmail, Mode=TwoWay}"
                    Placeholder="{i18n:Translate UserEmailPlaceholder}"
                    Style="{StaticResource entryStyle}">

                    <controls:ExtendedEntry.Behaviors>
                        <behavior:EventToCommandBehavior 
                            EventName="Focused" 
                            Command="{Binding ControlFocusCommand}"
                            CommandParameter="UserEmail"/>
                        <behavior:EventToCommandBehavior 
                            EventName="Unfocused" 
                            Command="{Binding ControlUnfocusedCommand}"
                            CommandParameter="UserEmail"/>
                    </controls:ExtendedEntry.Behaviors>

                </controls:ExtendedEntry>

                <Image
                    Grid.Row="0"
                    Grid.Column="1"
                    Source="clear.png"
                    IsVisible="{Binding IsEntryFocused}"
                    Style="{StaticResource imageClearStyle}">

                    <Image.GestureRecognizers>
                        <TapGestureRecognizer
                            Command="{Binding ClearCommand}"
                            CommandParameter="UserEmail"/>
                    </Image.GestureRecognizers>

                </Image>

                <Image
                    Grid.Row="1"
                    Grid.Column="0"
                    Grid.ColumnSpan="2"
                    Source="lineWhite.png"
                    Style="{StaticResource imageLineStyle}"/>

                <Image
                    Grid.Row="1"
                    Grid.Column="0"
                    Grid.ColumnSpan="2"
                    Source="linePure.png"
                    Style="{StaticResource imageLineStyle}"
                    IsVisible="{Binding IsError}"/>

                <Image
                    Grid.Row="1"
                    Grid.Column="0"
                    Grid.ColumnSpan="2"
                    Source="lineGradient.png"
                    Style="{StaticResource imageLineStyle}"
                    IsVisible="{Binding IsEntryFocused}"/>

                <Label
                    Grid.Row="2"
                    Grid.Column="0"
                    Text="{Binding ErrorMessage}"
                    Style="{StaticResource labelErrorStyle}"
                    IsVisible="{Binding IsError}"/>

                <Image
                    Grid.Row="2"
                    Grid.Column="1"
                    Source="error.png"
                    Style="{StaticResource imageErrorStyle}"
                    IsVisible="{Binding IsError}"/>

            </Grid>

我想重复使用它,例如如下:

<usercontrols:EntryControl 
                MainText="{Binding UserEmail}"
                MainTextPlaceholder="{i18n:Translate UserEmailPlaceholder}" />

现在即使这个简单的例子也不起作用,我不知道如何在这个控件中定义Command。现在我有:

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

    public static readonly BindableProperty MainTextProperty =
        BindableProperty.Create(
            propertyName: "MainText",
            returnType: typeof(string),
            declaringType: typeof(string),
            defaultValue: string.Empty,
            defaultBindingMode: BindingMode.TwoWay);

    public string MainText
    {
        get { return (string)this.GetValue(MainTextProperty); }
        set { this.SetValue(MainTextProperty, value); }
    }

    public static readonly BindableProperty MainTextPlaceholderProperty =
        BindableProperty.Create(
            propertyName: "MainTextPlaceholder", 
            returnType: typeof(string), 
            declaringType: typeof(string), 
            defaultValue: string.Empty, 
            defaultBindingMode: BindingMode.TwoWay);

    public string MainTextPlaceholder
    {
        get { return (string)this.GetValue(MainTextPlaceholderProperty); }
        set { this.SetValue(MainTextPlaceholderProperty, value);}
    }
}

这是正确的方法吗?或者这在Xamarin.Forms中是否可能?

2 个答案:

答案 0 :(得分:3)

XAML:

    <?xml version="1.0" encoding="utf-8" ?>
    <Grid xmlns="http://xamarin.com/schemas/2014/forms"
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
      x:Class="ApplicationName.Controls.EntryControl"
      Style="{StaticResource gridEntryStyle}">
    </Grid>

xaml.cs:

namespace ApplicationName.Controls
{
    public partial class EntryControl : Grid
    {
        public static readonly BindableProperty CommandProperty =
        BindableProperty.Create(
            propertyName: nameof(Command),
            returnType: typeof(ICommand),
            declaringType: typeof(EntryControl),
            defaultValue: null,
            defaultBindingMode: BindingMode.TwoWay);

        public string Command
        {
            get { return (string)this.GetValue(CommandProperty); }
            set { this.SetValue(CommandProperty, value); }
        }

        public EntryControl()
        {
            InitializeComponent();
        }
    }
}

使用:

xmlns:controls="clr-namespace:ApplicationName.Controls;assembly=ApplicationName"

<controls:EntryLabel/>

答案 1 :(得分:0)

您的BindingContext问题

简而言之,您必须写下控件内部的绑定,例如{Binding UserEmail,Mode = TwoWay, Source = {x:Reference myControlTHIS}} ,其中“ myControlTHIS”是x: Name =“ TheCategoryHeader”。


更多信息:

BindingContext是使事物绑定并在MVVM应用程序(WPF或Xamarin)中正常工作的一切。控件从父控件继承上下文,除非显式分配了其他上下文。这就是我们在这里要做的。我们需要告诉每个UI元素(标签,条目,按钮等)显式查看此控件的上下文,以便找到我们刚创建的BindingProperties。这是我们实际上给XAML元素命名的罕见情况之一:当XAML元素内的另一个XAML元素将其引用时。在ContentView中,添加一个标记为“ this”的标签。那就对了。我们将继续使用Microsoft的命名方式,并将其自身称为“ myControlTHIS”。它使我们所有人都感到舒适,并且代码和标记易于阅读和遵循。

我们现在可以使用“ myControlTHIS”作为参考源,告诉我们的XAML其余部分在哪里寻找要绑定的属性。