【问题标题】:How to nest views with bindings?如何使用绑定嵌套视图?
【发布时间】:2018-01-31 18:35:49
【问题描述】:

我正在使用带有 Prism 的 Xamarin.Forms。

给定一个具有街道、城市等属性的地点模型和一个允许用户定义两个地点(起始地点和目标地点)的路线视图,我想定义一个地点视图以包含在路线视图中以避免重复代码。

生成的 RouteView 可能是这样的

<label Text="Starting Place" />
<controls:PlaceView
   Place="{Binding StartingPlace}" />
<label Text="Target Place" />
<controls:PlaceView
   Place="{Binding TargetPlace}" />

Place 是 PlaceView 中的可绑定属性,StartingPlace 和 TargetPlace 是 Routes 视图模型中 Place 模型的实例。

我已经尝试通过

实现 PlaceView 中的绑定
<Label Text="Street" />
<Entry Text="{Binding Place.Street}" />

但这不起作用。 UI 中的更改不会导致 Place 实例的更改。

那么,将 Place 的属性绑定到嵌套视图的最优雅的方式是什么?我想避免在每个实例化中明确命名它们。

我有两个想法,最终如何实现,但我不确定如何实现它们。

  1. 为 PlaceView 创建一个视图模型并在那里创建属性,例如将 Street 连接到 Place.Street。这可能吗?如果是,那么如何从视图模型内部访问给定的地方?

  2. 在 Place View 的代码中实现此连接。这里我不知道该怎么做。

已编辑:

为了明确,模型如下

class Place
{
    private string _street;
    public string Street
    {
        get => _street;
        set => _street = value;
    }
}

编辑 2

这个like是当前的视图模型(RouteViewViewModel)

public class RouteViewViewModel : BindableBase
{
    private Place _startingPlace;
    public Place StartingPlace
    {
        get => _startingPlace;
        set => SetProperty(ref _startingPlace, value);
    }
    // TargetPlace is equivalent
}

Current Relationships

解决方案

感谢@Sharada Gururaj,我得到了一个结果,即available on Github

【问题讨论】:

  • 你设置了SetPropertyChanged(nameof(StartingPlace));和 SetPropertyChanged(nameof(TargetPlace));在模型中?
  • @PavanVParekh 你是什么意思?模型(Place)不知道它使用的上下文,因此模型中既没有 TargetPlace 也没有 StartingPlace。它只是一个包含 Street 和 City 等属性的普通类(请参阅已编辑的问题)。
  • 无论如何,您的(视图)模型都需要实现INotifyPropertyChanged。如果您为未实现此接口的类的属性创建 Bindings,您将无法更新 UI,并且(取决于 .NET Framework 版本)您可能会遇到内存泄漏。
  • 好的,Model (Place) 是一个简单的 C# 类,与 ViewModel (RouteViewViewModel) 之间似乎有些混淆。 RouteViewViewModel 确实实现了 BindableBase 并具有 StartingPlace 和 TargetPlace 的属性。对于嵌套的 PlaceView,目前没有 ViewModel。我的问题是关于实施一个是否可行和有帮助。

标签: c# xaml xamarin.forms prism


【解决方案1】:
  1. 为 PlaceView 创建一个视图模型并在那里创建属性,例如将 Street 连接到 Place.Street。这可能吗?如果是,那么如何从视图模型内部访问给定的地方?

答案是肯定的,拥有PlaceView 的视图模型会很有帮助 - 或者至少确保Place 实现属性更改通知,即INotifyPropertyChanged

  1. 在 Place View 的代码中实现此连接。在这里我不知道该怎么做。

一旦第 1 点完成 - 要么简单地更改您的绑定 以使用父控件作为 Source(并在 PlaceView XAML 中添加命名引用):

<ContentView x:Class="AppNamespace.PlaceView" x:Name="_parent">
        <Label Text="Street" />
        <Entry Text="{Binding Path=Place.Street, Source={x:Reference _parent}}" />

或使用BindingContext

<!-- PlaceView usage --> 
<controls:PlaceView BindingContext="{Binding StartingPlace}" />

<!-- Update binding in PlaceView control XAML -->
<Label Text="Street" />
<Entry Text="{Binding Path=Street}" />

【讨论】:

  • 那么,如果我为 PlaceView PlaceViewViewModel : Bindable Base 创建一个视图模型,我如何访问 ViewModels 类中绑定的 Place? IE。如何public string Street { set =&gt; _place.street = value; }?我在哪里可以从 View Model 内部获得 _place,它必须是来自 RouteView(即 StartingPlace/TargetPlace)的绑定 Place?
  • 我完全确定我是否理解您的问题 - 所以请耐心等待。
  • 如果您正在为 PlaceView 创建视图模型 - 那么您的 public Place StartingPlace 将变为 public PlaceViewModel StartingPlace 等等 RouteViewModel 中的其他属性;您需要将模型转换为视图模型。例如:您可以在 viewmodel public PlaceViewModel(Place place) { this.Street = place.Street; ... } 的构造函数中执行此操作
  • 在您的帮助下做到了!非常感谢!对于遇到这个问题的其他人,我创建了一个GitHub repository which contains the running result
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-19
  • 2020-02-12
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 2021-10-24
  • 2013-05-31
相关资源
最近更新 更多