Prism注入带自定义属性的XAML IValueConverter时绑定报错的解决方法
问题描述
我正在使用Prism开发Xamarin MVVM应用,实现了一个同时继承IValueConverter和INotifyPropertyChanged的MyConverter,代码如下:
public class MyConverter: IValueConverter, INotifyPropertyChanged { private readonly IMyInjectedService _myInjectedService; public UnitVisualizationConverter(IMyInjectedService myInjectedService) { _myInjectedService = myInjectedService; } private string _myProperty= null; public event PropertyChangedEventHandler PropertyChanged; public string MyProperty { get => _myProperty; set { _unit = _myProperty; OnPropertyChanged(); } } protected virtual void OnPropertyChanged(string propertyName = null) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { //some code } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { // some code } }
该转换器通过构造函数注入IMyInjectedService,同时包含可绑定的MyProperty属性。我尝试在XAML中通过ContainerProvider获取该转换器并将MyProperty绑定到ViewModel的对应属性,代码如下:
<ResourceDictionary> <ioc:ContainerProvider x:TypeArguments="valueConverters:MyConverter" x:Key="MyConverter" MyProperty ="{Binding DataContext.MyProperty}"/> </ResourceDictionary>
但运行时出现错误:The property 'MyProperty' was not found in type 'ContainerProvider1'`,请问该如何解决这个问题?
解决方案
核心原因
ContainerProvider<T>本身并没有MyProperty属性,直接在ContainerProvider标签上设置MyProperty绑定,XAML解析器会判定该属性属于ContainerProvider,自然找不到对应定义,所以抛出错误。
具体解决方法
- 使用Prism的
ContainerBinding绑定属性
Prism提供了ContainerBinding专门用于为容器解析的对象设置属性绑定,无需直接操作ContainerProvider的属性,是官方推荐的方式:
<ResourceDictionary> <ioc:ContainerProvider x:TypeArguments="valueConverters:MyConverter" x:Key="MyConverter"/> <ioc:ContainerBinding Target="{StaticResource MyConverter}" PropertyName="MyProperty" Binding="{Binding DataContext.MyProperty}"/> </ResourceDictionary>
这段代码会自动获取容器解析的MyConverter实例,并为其MyProperty属性设置绑定,完全避开XAML解析错误。
- 修正转换器代码中的基础错误
你的转换器代码存在两个必改的问题,否则即使绑定成功也会出现逻辑错误:
- 构造函数名错误:
UnitVisualizationConverter应改为MyConverter,否则无法正确实例化 MyProperty的setter逻辑错误:_unit = _myProperty应改为_myProperty = value,否则属性值不会更新- 优化
OnPropertyChanged方法:使用null条件运算符简化代码,同时明确传入属性名
修正后的关键代码:
public MyConverter(IMyInjectedService myInjectedService) { _myInjectedService = myInjectedService; } public string MyProperty { get => _myProperty; set { _myProperty = value; OnPropertyChanged(nameof(MyProperty)); } } protected virtual void OnPropertyChanged(string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); }
内容的提问来源于stack exchange,提问作者Brudi_Voeller
相关产品推荐
相关产品推荐

