[英]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
属性绑定到usersPage
的BindingContext
属性,有没有办法克服这一问题(最好是一个干净的方法...)?
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.