【问题标题】:Xamarin.Forms MVVM two way binding between Entry and Property not working(Entry.Text not updated with PropertyChanged)Xamarin.Forms MVVM Entry 和 Property 之间的两种方式绑定不起作用(Entry.Text 未使用 PropertyChanged 更新)
【发布时间】:2020-03-12 04:37:28
【问题描述】:

问题已解决,创建此问题是因为此特定情况不在线。

澄清一下,根据https://docs.microsoft.com/en-us/xamarin/xamarin-forms/xaml/xaml-basics/data-bindings-to-mvvmMicrosoft 的 Xamarin MVVM 文档,一切都已正确实施

BindingContext、OnAppearing、INotifyPropertyChanged 等都是完美的。

情况

  1. 我有一个带有客户端对象列表的选择器。
  2. 我有 4 个条目,每个条目都有两种方式绑定到 Location 对象中的属性。例如。
<Entry x:Name="StreetName_Entry"
       Text="{Binding Location.StreetName, Mode=TwoWay}"/>
  1. 当在客户端选择器中选择客户端时,程序需要获取与客户端对象关联的地址对象,并将该地址对象中的每个属性应用到位置对象(地址和位置在结构上相同) 例如
public async void SetLocationAsClientAddress()
        {
            Client client = Client;
            Address clientsAddress;
            if (client != null)
            {
                clientsAddress = await Database.GetAddressFor(client);
                // Location is a property in the ViewModel, as well as an object type
                Location.StreetNumber = clientsAddress.StreetNumber;
                Location.StreetName = clientsAddress.StreetName;
                Location.Suburb = clientsAddress.Suburb;
                Location.Postcode = clientsAddress.Postcode;
            }
        }
  1. 因为位置对象属性现在填充了数据,这些应该立即显示在 4 Entry.text 中,因为有两种方式绑定。他们没有。

【问题讨论】:

    标签: c# mvvm xamarin.forms data-binding


    【解决方案1】:

    解决方案:

    在 ViewModel 中编辑对象的单个属性时不会触发 PropertyChanged 事件。因此,即使属性实际上已更改,视图也不知道,因为未触发事件。 因此,不要更改单个属性(无论如何这都是不好的做法),而是使用对象的构造函数并用新对象覆盖旧对象。例如

    public async void SetLocationAsClientAddress()
            {
                Client client = Client;
                Address clientsAddress;
                if (client != null)
                {
                    clientsAddress = await Database.GetAddressFor(client);
                    // Location is a property in the ViewModel, as well as an object type
                    Location = new Location(0, clientsAddress.StreetNumber, clientsAddress.StreetName, clientsAddress.Suburb, clientsAddress.Postcode);
                }
            }
    

    通过这种方式,PropertyChanged 事件知道 ViewModel 属性(它是一个对象)是不同的,并让 View 知道。

    【讨论】:

    • 另一种解决方案是在 Location 类上也实现 INPC
    • INPC 已在 Location 类上实现。我只有在编辑本身是 ViewModel 中的属性的对象的属性时才出现问题,如示例所示。这是一个边缘案例,我在其他地方找不到任何例子。
    • 抱歉,我无法重现您的问题 - 事实上,这不是极端情况,而是非常常见的情况。
    • 这应该可以正常工作,假设 Location 类在其属性上正确实现了 INotifyPropertyChanged。您可能需要共享该代码。
    • 另一种方法是在更改其内部属性后手动引发 Location 属性的属性更改事件。根据您实施 INPC 的方式,它可能类似于 OnPropertyChanged(nameOf(Location));
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    相关资源
    最近更新 更多