MAUI.NET 对失去焦点的更新绑定一样

MAUI.NET update binding on lost focus alike

提问人:jaydopartu 提问时间:5/21/2023 最后编辑:jaydopartu 更新时间:5/29/2023 访问量:555

问:

介绍:

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

需要:

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

例:

如果用户输入 Entry 并输入 VM 中绑定属性上的 set funciton,则在按下每个键后将触发 4 次。我希望它在用户使用此 Entry 控件结束后只触发一次。1234

尝试:

好像太基础了......我已经试过了:

  • 找到等效项(就像我们在 WPF 中所做的那样)UpdateSourceTrigger="LostFocus"
  • 尝试将 UpdateSourceEventName 与 或 一起使用CompletedUnfocused
  • 尝试手动更新此绑定 - 我设法通过检查 Unfocused 事件的第二个参数来捕捉用户离开 Entry 的时刻,但找不到等效项(就像我们在 WPF 中所做的那样),而且只有没有什么可以得到它......private void Entry_Unfocused(object sender, FocusEventArgs e) { if(!e.IsFocused) { ...BindingOperations.GetBindingExpressionsender as EntrySetBinding
  • 谷歌搜索了将近 2 个小时......

编辑:我的解决方法:

我已经设法做了这样的疯狂解决方法:

  • 在我的 ViewModel 中,我做了一个额外的属性,如 ValueTemp,它绑定到 Entry 的 Text 属性。视图绑定到此属性。
  • ViewModel 中的旧 Value 属性绑定到 Placeholder(必须绑定到触发 getter 的东西,也许我会使用转换器或一些不可见的标签进行多重绑定),并且在它的 getter 期间,我将值设置为 ValueTemp
  • Entry_Unfocused事件期间,我将获取 ValueTemp 并将其设置为旧的 Value 属性。在我的情况下,不知何故完成不会触发。
  • 有一些技巧可以正确进行 PropertyChanged 和双向同步。
  • 实际上,我的代码要复杂得多,这就是为什么很难在这里放一些代码的原因。但总的来说,我在 VM 中使用了一个额外的属性并将其绑定用于视图目的,当用户完成编辑时,我将其值设置为我的正确属性,以便以后可以处理它。
C# XAML 绑定 Maui 失去焦点

评论

0赞 Jason 5/21/2023
learn.microsoft.com/en-us/dotnet/api/......
0赞 jaydopartu 5/22/2023
谢谢你的提示。但是,不太确定如何通过此限制 VM 中绑定属性的更新?此 Completed 事件只是关于 Unfocused 事件和检查其参数的 e.IsFocused 的替代方法,对吧?
0赞 jaydopartu 5/22/2023
顺便说一句 - 不知道为什么,但是在我输入并按下 TAB 按钮后Entry_Completed事件没有被击中。无论如何。。。即使它开火了......如何手动更新与 VM 的绑定,以及如何限制其更新,直到此刻?此致敬意1234
1赞 Jason 5/22/2023
我不会对条目使用绑定,而只是在事件触发时手动更新 VM
0赞 Sir Rufo 5/22/2023
这种绑定的真正问题是什么?任何性能问题?

答:

2赞 Sir Rufo 5/29/2023 #1

您可以按照 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>

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