刷新 .NET MAUI 中的绑定

问题描述 投票:0回答:3

我有一个场景,使用

INotifyPropertyChanged
接口从 ViewModel 更新 View 是不合适的。

相反,我想显式刷新一些绑定。

在 WPF 中,这似乎可以通过从控件获取

BindingExpression
并调用
BindingExpression.UpdateTarget()
来实现(请参阅如何强制刷新 WPF 绑定?)。

毛伊岛也可能有类似的事情吗?

BindingExpression
根本不存在...

背景

我正在显示一个项目列表,每个项目都有一个

CreatedAt
时间戳。例如,在用户界面中,我想将其显示为“7 分钟前”。因此,我创建了一个值转换器,将
DateTime
转换为字符串。当然,显示的字符串应该随着时间的推移而更新。

恕我直言,在这种情况下,更新 UI 中的文本应该是视图的问题。我不想在我的 ViewModel 中有间隔计时器。我更喜欢在我的视图中(在后面的代码中)有一个间隔计时器,它只刷新当前可见的那些项目的绑定。

xaml data-binding maui
3个回答
0
投票

“恕我直言,更新 UI 中的文本应该是 View 的问题 这个案例。我不想在我的 ViewModel 中有间隔计时器。我 更喜欢在我的视图中(在后面的代码中)有一个间隔计时器 仅刷新当前可见的那些项目的绑定。”

我想指出一些关于 MVVM 的重要内容。

遵循 MVVM 架构时,ViewModel 不应该了解有关 View 的任何信息。但是,您的视图始终可以访问 ViewModel。

您可以随时从 ViewModel 调用方法。无论是作为对事件的响应、收到的消息还是其他东西。

您的 View 应该已经保存了对 ViewModel 的引用,因此通过创建计时器并调用方法来更新数据,您将不会违反任何 MVVM 原则。

(如果我还没有说服你,请告诉我继续...)


0
投票

不幸的是,Maui 缺乏任何方法来访问绑定表达式。

一种解决方案是创建执行您想要的操作的视图属性,并在计时器上触发属性更改:

<Label Text="{Binding RelativeTime1, Source={RelativeSource Self}}" />

在视图的代码隐藏中:

MyViewModel VM => BindingContext as MyViewModel;

public RelativeTime1 => AsRelativeTime(VM.Time1);

// Each timer tick
public void Elapsed()
{
   OnPropertyChanged(nameof(RelativeTime1));
}

0
投票

在 Xamarin 情况下,我使用这个辅助方法(我希望在 MAUI 中也一样)

internal static void ApplyBinding(this BindableObject bindableObject, BindableProperty property)
{
    var binding = bindableObject.GetBindableObject(property);
    var tBinding = typeof(BindingBase);
    var mUnapply = tBinding.GetMethod("Unapply", BindingFlags.NonPublic | BindingFlags.Instance);
    mUnapply?.Invoke(binding, new object[] { false });
    var mApply = tBinding.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance)
        .FirstOrDefault(v => v.Name == "Apply" && v.GetParameters().Length > 2);
    mApply?.Invoke(binding, new[] { bindableObject.BindingContext, bindableObject, property, false });
}

计时器“Elapsed”后面的代码中的用法是(如果我们在自定义 TabView 类中)

this.ApplyBinding(TabItemsSourceProperty);
© www.soinside.com 2019 - 2024. All rights reserved.