简体   繁体   English

Xamarin.Forms:如何获取引用绑定上的属性通知

[英]Xamarin.Forms: How to get property notification on reference binding

Consider the following pseudo code. 考虑下面的伪代码。

ViewModel: 视图模型:

public class ViewModel
{
    IEnumerable<string> _AvailableNames
    public IEnumerable<string> AvailableNames
    {
        get => _AvailableNames;
        set => SetProperty(ref _AvailableNames, value); //Notifies
    }
}

View: 视图:
ContentPage 's ViewModel is a ViewModel instance set by dependency injection. ContentPage的ViewModel是通过依赖项注入设置的ViewModel实例。

<ContentPage x:Name="page" prism:ViewModelLocator.AutowireViewModel="True">
    <Element BindingContext="{Binding SelectedElement}">
        <ListView ItemsSource="{Binding BindingContext.AvailabeNames, Source={Reference page}}" />
    </Element>
</ContentPage>

The AvailableNames property gets updated on demand, but doesn't get reflected in the UI. AvailableNames属性会按需更新,但不会反映在UI中。 I suspect it's because the bound property is BindingContext.AvailableNames , is that so? 我怀疑是因为绑定的属性是BindingContext.AvailableNames ,是这样吗? I mean it binds to the AvailableNames property, but doesn't get updated when the property changes. 我的意思是它绑定到AvailableNames属性,但是当属性更改时不会更新。

Note, I tried making AvailableNames a get-only ObservableCollection but adding values to it doesn't reflect to the page either. 请注意,我尝试将AvailableNames设置为仅获取的ObservableCollection但是向其中添加值也不会反映在页面上。

I understand that this is because the ItemsSource property is bound to the BindingContext property of the usersPage , is there a way to overcome this (preferably a clean one...)? 我知道这是因为ItemsSource属性绑定到usersPageBindingContext属性,有没有办法克服这一问题(最好是一个干净的方法...)?

For my scenario, it was enough to set back the BindingContext to the upper property (ie the ViewModel), this will be a limitation in some other scenarios, for instance if I'm binding from within a ListView etc. 对于我的场景,将BindingContext设置回上层属性(即ViewModel)就足够了,这在某些其他场景中是一个限制,例如,如果我是从ListView绑定等。

So the solution is to set it as follows: 因此解决方案是将其设置如下:

<ListView
  BindingContext="{Binding BindingContext, Source={Reference usersPage}}"
  ItemsSource="{Binding AvailabeNames}"/>

In some scenarios, another option would be a better solution, wrap it with a dummy control like so: 在某些情况下,另一个选择会是一个更好的解决方案,用一个虚拟控件包装它,如下所示:

<ContentView BindingContext="{Binding BindingContext, Source={Reference usersPage}}">
  <ListView ItemsSource="{Binding AvailableItems}"/>
</ContentView>

I don't know why, but for some controls expecting some value other than string (ie Switch ) I can't seem to bind this even with the converter as the value doesn't update. 我不知道为什么,但是对于某些期望除string以外的值的控件(即Switch ),即使值不更新,我似乎也无法将其绑定。 The solution to that is use a dummy control getting the string representation of the value. 解决方案是使用虚拟控件获取值的字符串表示形式。
In my case I'm using the MultiBinding class, that even its converter always returns bool (otherwise will internally throw a NullReferenceException and will display nothing), still doesn't update itself properly. 在我的情况下,我使用的是MultiBinding类,即使其转换器始终返回bool (否则将在内部抛出NullReferenceException且不显示任何内容),但仍无法正确更新。 With a 3rd party property it works well: 具有第三方属性,效果很好:

<Label x:Name="dummyLabel" Text="{MultiBinding}"/>
<Switch IsToggled="{Binding Text, Source={Reference dummyLabel}}"/>

Obviously I'm not a fan of this hacky and ugly code, but that's the only way I found that works. 显然,我不喜欢这种hacky和丑陋的代码,但这是我发现可行的唯一方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM