【问题标题】:Xamarin Forms how to add behaviors to custom controlXamarin Forms 如何向自定义控件添加行为
【发布时间】:2019-11-21 00:40:53
【问题描述】:

我创建了一个自定义控件,它是一个ContentView,带有一个Label 和一个Entry

自定义控件的xaml 如下所示:

<Label Text="{Binding Source={x:Reference ValidationControl}, Path=Caption}"/>
<Entry Text="{Binding Source={x:Reference ValidationControl}, Path=Value, Mode=TwoWay}" />

自定义控件的代码如下:

public static readonly BindableProperty CaptionProperty = BindableProperty.Create(
    nameof(Caption), typeof(string), typeof(ValidationEntry), default(string));

public string Caption
{
    get => (string)GetValue(CaptionProperty);
    set => SetValue(CaptionProperty, value);
}

public static readonly BindableProperty ValueProperty = BindableProperty.Create(
    nameof(Value), typeof(string), typeof(ValidationEntry), default(string));

public string Value
{
    get => (string)GetValue(ValueProperty);
    set => SetValue(ValueProperty, value);
}

我使用自定义控件的方式如下

<controls:ValidationEntry Caption=”Name:” Value="{Binding FullName, Mode=TwoWay}" />

我的问题是如何向自定义控件添加行为?
我想将它们添加到我使用控件的地方。即

<controls:ValidationEntry Caption="Name:"
                          Value="{Binding FullName, Mode=TwoWay}">
    <controls:ValidationEntry.EntryBehaviors>
        <behaviors:EntryLengthValidatorBehavior IgnoreSpaces="True"/>
    </controls:ValidationEntry.EntryBehaviors>
</controls:ValidationEntry>

【问题讨论】:

    标签: xamarin.forms custom-controls behavior


    【解决方案1】:

    您可以直接创建行为,我在自定义条目中添加了一个 NumericValidationBehavior 来检查数据是否为双精度。如果数据类型不是双精度,则将文本颜色设置为红色。

    这里是 xaml 代码。

    <StackLayout>
    <local:MyEntry   local:NumericValidationBehavior.AttachBehavior="true">
    
    
    </local:MyEntry>
    </StackLayout>
    

    这里是 NumericValidationBehavior.cs

         public static class NumericValidationBehavior
    {
        public static readonly BindableProperty AttachBehaviorProperty =
            BindableProperty.CreateAttached(
                "AttachBehavior",
                typeof(bool),
                typeof(NumericValidationBehavior),
                false,
                propertyChanged: OnAttachBehaviorChanged);
    
        public static bool GetAttachBehavior(BindableObject view)
        {
            return (bool)view.GetValue(AttachBehaviorProperty);
        }
    
        public static void SetAttachBehavior(BindableObject view, bool value)
        {
            view.SetValue(AttachBehaviorProperty, value);
        }
    
        static void OnAttachBehaviorChanged(BindableObject view, object oldValue, object newValue)
        {
            var entry = view as Entry;
            if (entry == null)
            {
                return;
            }
    
            bool attachBehavior = (bool)newValue;
            if (attachBehavior)
            {
                entry.TextChanged += OnEntryTextChanged;
            }
            else
            {
                entry.TextChanged -= OnEntryTextChanged;
            }
        }
    
        static void OnEntryTextChanged(object sender, TextChangedEventArgs args)
        {
            double result;
            bool isValid = double.TryParse(args.NewTextValue, out result);
            ((Entry)sender).TextColor = isValid ? Color.Default : Color.Red;
        }
    }
    

    更新

    我用 ContentView 创建了一个自定义视图

    <ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="BeHavDemo.MyView">
     <ContentView.Content>
         <StackLayout>
            <Label Text="xxxx"/>
            <Entry Text="eeeee" />
          </StackLayout>
      </ContentView.Content>
    </ContentView>
    

    然后我创建一个行为。

        public  class MyBeha : Behavior<MyView>
    {
        protected override void OnAttachedTo(BindableObject view)
        {
            base.OnAttachedTo(view);
    
            var myview=view as MyView;
            StackLayout stackLayout = (StackLayout)myview.Content;
    
            Label label = (Label)stackLayout.Children[0];
           Entry entry=(Entry) stackLayout.Children[1];
    
        }
    }
    

    【讨论】:

    • 这是一个有趣的方法!我还没有检查它是否有效,但我会尽快完成。这与我描述的不完全一样,也不确定是否可以在自定义控件之外使用此行为。无论如何,这是一个有趣的解决方案。
    • 它不起作用。问题是在NumericValidationBehaviorOnAttachBehaviorChanged 中,您将BindableObject view 转换为Entry。我的自定义控件不是Entry,但它包含Entry,它只是一个示例,因此它可能包含 2 个条目(即具有国家前缀和号码的电话控件)。如果我将行为放在自定义控件的Entry 中并数据绑定AttachBehavior 以便我可以打开或关闭它,它可能会起作用,但这有点麻烦。我正在寻找一种添加行为的方法,就像我在帖子末尾所描述的那样。
    • @Dimitris 如果你想为组合视图设置一个行为,你可以在自定义渲染器中实现这个行为,针对不同平台实现这个行为,比如这个线程docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/…,判断control的状态并为此Control设置效果。
    • Lu 为什么我需要创建自定义渲染器?控件上没有任何依赖于平台的东西!我要问的是如何处理自定义控件中的行为列表。
    • @Dimitris 很抱歉,我对另一个链接感到困惑。我创建了一个自定义视图,您可以看到我的更新答案,我可以通过 BindableObject 获取条目和标签
    猜你喜欢
    • 1970-01-01
    • 2020-01-30
    • 1970-01-01
    • 1970-01-01
    • 2020-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-19
    相关资源
    最近更新 更多