【问题标题】:Pass Parameter into Xamarin Forms Behaviour将参数传递到 Xamarin 表单行为
【发布时间】:2017-02-15 00:03:02
【问题描述】:

我的应用中有一个表单,我正在使用行为进行客户端验证。 我想将一个值传递给最大验证器的行为。
值存储在我的 ViewModel 中,我试图将值传递给行为,但是它将零传递给行为而不是值。 我尝试使用硬编码值,效果很好。

我的问题是:
是否可以将 ViewModel 属性传递给行为?

XAML:

<Entry Text="{Binding EventSubscription.Attendees, Mode=TwoWay }"  WidthRequest="50"   x:Name="attendees"  >
    <Entry.Behaviors>
        <behaviours:NullEntryValidationBehaviour x:Name="GroupValidator"/>
        <behaviours:MaxAttendeesValidationBehaviour Max="{Binding EventSubscription.RemainingPlaces, Mode=TwoWay}"/>
    </Entry.Behaviors>
</Entry>

C# 行为:

public class MaxAttendeesValidationBehaviour : Behavior<Entry>
{
    
    public static BindableProperty IntProperty = BindableProperty.Create<MaxAttendeesValidationBehaviour, string>(tc => tc.MaxAttendeesAllowed, string.Empty, BindingMode.TwoWay);

    public string MaxAttendeesAllowed
    {
        get
        {
            return (string)GetValue(IntProperty);
        }

        set
        {
            SetValue(IntProperty, value);
        }
    }

    protected override void OnAttachedTo(Entry bindable)
    {
        bindable.TextChanged += HandleTextChanged;
        base.OnAttachedTo(bindable);
    }

    void HandleTextChanged(object sender, TextChangedEventArgs e)
    {
        bool IsValid = false;
        if (!string.IsNullOrEmpty(e.NewTextValue))
        {
            IsValid = true;//Int32.Parse(e.NewTextValue) <= MaxAttendeesAllowed;
        }                     
        ((Entry)sender).TextColor = IsValid ? Color.Default : Color.Red;
    }  
  
    protected override void OnDetachingFrom(Entry bindable)
    {
        bindable.TextChanged -= HandleTextChanged;
        base.OnDetachingFrom(bindable);
    }
}

【问题讨论】:

    标签: c# mvvm xamarin.forms


    【解决方案1】:

    你可以这样做:

    public class MaxValueEntry : Behavior<Entry>
    {
        public int Max { get; set; }
    
        protected override void OnAttachedTo(Entry entry)
        {
            entry.TextChanged += OnEntryTextChanged;
            base.OnAttachedTo(entry);
        }
    
        protected override void OnDetachingFrom(Entry entry)
        {
            entry.TextChanged -= OnEntryTextChanged;
            base.OnDetachingFrom(entry);
        }
    
        void OnEntryTextChanged(object sender, TextChangedEventArgs args)
        {
            if(args.NewTextValue.Length > Max)
                ((Entry)sender).TextColor = Color.Red;
            else
                ((Entry)sender).TextColor = Color.Default;
        }
    }
    

    然后在您的 xaml 中,添加如下参数:

      <Entry>
        <Entry.Behaviors>
          <behaviors:MaxValueEntry Max="3"/>
        </Entry.Behaviors>
      </Entry>
    

    如果你需要从视图模型中绑定值,你应该为Max创建一个可绑定属性

    像这样:

    public static readonly BindableProperty MaxProperty =
    BindableProperty.CreateAttached("Max", typeof(int), typeof(MaxValueEntry), 0);
    
    public int Max
    {
        get { return (int)GetValue(MaxProperty); }
        set { SetValue(MaxProperty, value); }
    }
    

    【讨论】:

    • 在 Bindable 属性始终为 0 的情况下也会出现同样的问题。由于某种原因,该属性没有被传递给行为
    • 不确定是否仍然需要,但可能会为未来的开发人员服务。根据设计,行为不会传播视图的 BindingContext,因此它们可以跨多个视图重用,从而减少对 GC 的压力。见 [1] 和 [2]。如果您浏览 Xamarin 论坛帖子,您会发现一个指向可能有所帮助的要点 [3] 的链接。 [1]:forums.xamarin.com/discussion/comment/101682 [2]:bugzilla.xamarin.com/show_bug.cgi?id=26521 [3]:gist.github.com/Yortw/f4b1220296de0a1d53ce
    • 如何在使用绑定的集合的视图中传入参数?它似乎对我不起作用。
    • 对于将来发现此问题的任何人,您需要在行为中手动添加绑定上下文:protected override void OnAttachedTo(BindableObject bindable) { base.OnAttachedTo(bindable); bindable.BindingContextChanged += (sender, _) => this.BindingContext = ((BindableObject)sender).BindingContext; }
    猜你喜欢
    • 2021-03-21
    • 1970-01-01
    • 1970-01-01
    • 2020-07-08
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多