XAML MAUI.NET更新绑定在丢失的焦点上

0dxa2lsx  于 2023-06-03  发布在  .NET
关注(0)|答案(1)|浏览(202)

简介:

使用带有MVVM架构的MAUI.NET,但MVVM可能会被牺牲(这一需求对应用程序非常重要)。标准方式-我有一个ViewModel,它有一个属性,其中get和set实现了INotifyPropertyChanged,并将这个属性绑定到具有上述ViewModel的BindingContext的视图中的Entry的Text属性。

需求:

需要在用户退出Entry(单击控件外部的某个位置或按键盘上的Tab键)后执行绑定(调用set属性)。默认的绑定情况是用户每次击键时都执行绑定。

示例:

如果用户输入Entry并输入1234,则VM中绑定属性的set函数将在每次按键后触发4次。我希望它火后,用户只与此进入控制结束一次。

尝试次数:

看起来很基本。。我已经试过了:

  • 查找UpdateSourceTrigger="LostFocus"的等价项(就像我们在WPF中所做的那样)
  • 尝试将UpdateSourceEventName与CompletedUnfocused一起使用
  • 尝试手动更新此绑定-我设法通过检查未聚焦事件private void Entry_Unfocused(object sender, FocusEventArgs e) { if(!e.IsFocused) { ...的第二个参数来捕捉用户离开条目的时刻,但无法找到与BindingOperations.GetBindingExpression等效的事件(就像我们在WPF中所做的那样),此外,在sender as Entry上只有SetBinding,而没有任何东西可以获得它...
  • google了将近两个小时
    编辑:我的解决方法:

我做了一些疯狂的工作:

  • 在我的ViewModel中,我做了一个额外的属性,如ValueTemp,它绑定到Entry的Text属性。视图绑定到此属性。
  • ViewModel中的旧Value属性绑定到Placeholder(必须绑定到某个东西才能触发getter,也许我会使用converter或某个不可见的标签进行多重绑定),在getter期间,我将值设置为ValueTemp
  • 在Entry_Unfocused事件期间,我获取ValueTemp并将其设置为旧的Value属性。在我的情况下,“以某种方式完成”不会触发。
  • 这里有一些技巧来实现正确的PropertyChanged和双向同步。
  • 实际上我的代码要复杂得多,这就是为什么很难在这里放一些代码。但一般来说,我在VM中使用一个额外的属性,并将其绑定为视图,当用户完成编辑时,我将其值设置为适当的属性,以便稍后处理。
2ekbmq32

2ekbmq321#

您可以按照MAUI文档中的描述为此编写一个行为。
在此行为中,您为ViewModel的绑定声明了一个附加属性,并订阅条目的Unfocused事件以更新附加属性。

public class EntryLostFocusBehavior : Behavior<Entry>
{
    public static readonly BindableProperty TextProperty = BindableProperty.CreateAttached(
        "Text",
        typeof( string ),
        typeof( EntryLostFocusBehavior ),
        null,
        BindingMode.TwoWay,
        propertyChanged: TextPropertyChanged );

    public static string GetText( Entry entry ) => (string)entry.GetValue( TextProperty );
    public static void SetText( Entry entry, string value ) => entry.SetValue( TextProperty, value );

    private static void TextPropertyChanged( BindableObject bindable, object oldValue, object newValue )
    {
        var entry = (Entry)bindable;
        entry.Placeholder = newValue as string;
    }

    protected override void OnAttachedTo( Entry bindable )
    {
        base.OnAttachedTo( bindable );
        bindable.Unfocused += Entry_Unfocused;
    }

    protected override void OnDetachingFrom( Entry bindable )
    {
        base.OnDetachingFrom( bindable );
        bindable.Unfocused -= Entry_Unfocused;
    }

    private void Entry_Unfocused( object sender, FocusEventArgs e )
    {
        var entry = (Entry)sender;
        SetText( entry, entry.Text );
    }
}

在你的视图中使用这个

<Page ...
      xmlns:b="clr-namespace:MyMauiApp.Behaviors"
      ...>

  <Entry b:EntryLostFocusBehavior.Text="{Binding Value1}">
      <Entry.Behaviors>
          <b:EntryLostFocusBehavior />
      <Entry.Behaviors>
  </Entry>

  <Entry b:EntryLostFocusBehavior.Text="{Binding Value2}">
      <Entry.Behaviors>
          <b:EntryLostFocusBehavior />
      <Entry.Behaviors>
  </Entry>

</Page>

这就是视图/视图模型。没有代码隐藏,没有其他属性。

相关问题