繁体   English   中英

Xamarin.Forms中的可重用XAML控件

[英]Reusable XAML control in 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中甚至有可能?

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/>

您的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其余部分在哪里寻找要绑定的属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM