绑定错误:WPF 正在寻找错误对象的属性

Posted

技术标签:

【中文标题】绑定错误:WPF 正在寻找错误对象的属性【英文标题】:Binding error: WPF is looking for property on wrong object 【发布时间】:2015-10-11 20:50:52 【问题描述】:

我有一个名为 ObservationEditorHost 的用户控件(令人惊讶的是)它充当另一个名为 ObservationEditor 的用户控件的主机页面。 我在输出窗口中遇到绑定错误,在 ObservationEditorHost 的 XAML 中,ObservationEditor 的实例带有下划线,并且工具顶部显示“对象引用未设置为对象的实例”。

输出窗口中的错误信息是:

System.Windows.Data 错误:40:BindingExpression 路径错误: 在“对象”上找不到“DataProviderID”属性 ''ObservationEditorViewModel' (HashCode=38856023)'。 BindingExpression:Path=DataProviderID; DataItem='ObservationEditorViewModel' (HashCode=38856023);目标 元素是'ObservationEditor'(名称='');目标属性是 “ExclusiveDataProviderID”(类型“Int32”)

问题:我的目标当然是解决绑定错误,但我无法做到。错误消息是此绑定的结果(完整的语句也显示在下面的代码中)

ExclusiveDataProviderID="Binding DataProviderID"

我的困惑来自错误消息的这一部分:'DataProviderID' property not found on 'object' ''ObservationEditorViewModel'。

请注意以下代码中的以下内容:

DataProviderID 是 ObservationEditorHost 的一个属性(不是 ObservationEditor 或 ObservationEditorViewModel 如 错误信息)。 ObservationEditorHost 的 DataContext 设置为 自己在构造函数中。

鉴于上述两个参数,我不明白 WPF 如何/为什么在 ObservationEditorViewModel 上查找 DataProviderID,如错误消息中所述。

我已经解决了问题:

从所有项目中删除了 bin 和 obj 目录 重新启动 Visual Studio 将 DataProviderID 的名称更改为 zzzDataProviderID 以确保错误消息实际上涉及 到这个属性,而不是同名的不同属性 一个子控件。 搜索了 ObservationEditorViewModel 的整个解决方案,以确保我没有将其设置在其他地方

ObservationEditorHost 之间的所有其他绑定 和 ObservationEditor 似乎工作并且没有其他错误 消息。绑定的目标 ExclusiveDataProviderID 是 如我的代码所示,绑定到 DataProviderId 时未设置。 但是,当我绑定到如下所示的常量时, ExclusiveDataProviderID 设置正确:

--- 代码---

ObservationEditorHost.xaml(这是整个控件。仅删除了 xaml 命名空间)

<dxdo:DocumentPanel x:Class="VVM.ObservationEditorHost"
         mc:Ignorable="d" Caption="Observation Editor"
         Description="Observation Editor">
    <components:ObservationEditor ShowSeriesSelector="True" ExclusiveDataProviderID="Binding DataProviderID"></components:ObservationEditor>
</dxdo:DocumentPanel>

ObservationEditorHost.xaml.cs(逐字)

public partial class ObservationEditorHost : DocumentPanel, INotifyPropertyChanged

    private int _DataProviderID;
    public int DataProviderID 
    
        get  return _DataProviderID; 
        set
        
            if (_DataProviderID != value)
            
                _DataProviderID = value;
                RaisePropertyChanged();
            
        
    

    public ObservationEditorHost(DataProvider dp)
    
        InitializeComponent();
        DataProviderID = dp.ID;
        DataContext = this;
    

    #region INotifyPropertyChanged implementation
    public event PropertyChangedEventHandler PropertyChanged;

    public void RaisePropertyChanged([CallerMemberNameAttribute] string propertyName = "")
    
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    
    #endregion

我无法提供 ObservationEditor.xaml.cs 的完整代码,因为它非常大。不过我会提供这个相关部分:

public partial class ObservationEditor : UserControl


    public int ExclusiveDataProviderID
    
        get  return (int)GetValue(ExclusiveDataProviderIDProperty); 
        set  SetValue(ExclusiveDataProviderIDProperty, value); 
    

    public static readonly DependencyProperty ExclusiveDataProviderIDProperty =
        DependencyProperty.Register("ExclusiveDataProviderID", typeof(int), typeof(ObservationEditor), new PropertyMetadata(0, ExclusiveDataProviderID_Changed));

    public ObservationEditor()
    
        InitializeComponent();
        ObservationEditorViewModel vm = ObservationEditorViewModel.Create().Result;
        DataContext = vm;
    
   

【问题讨论】:

【参考方案1】:

问题是您正在尝试使用 ObservationEditorHost 中的属性,但您的 DataContext 是 ObservationEditorViewModel。

我认为您应该能够使用 FindAncestor 来定位正确的控件:

ExclusiveDataProviderID="Binding DataProviderID, RelativeSource=
    RelativeSource FindAncestor, AncestorType=x:Type DocumentPanel"

ObservationEditorHost 的 DC 是 ObservationEditorHost 的代码隐藏。

ObservationEditor 已将其 DC 手动设置为 ObservationEditorViewModel:

ObservationEditorViewModel vm = ObservationEditorViewModel.Create().Result;
DataContext = vm;

绑定引擎正在尝试使用您在构造函数中设置的上下文(视图模型)解析 DataProviderID 的绑定。

这一行的绑定:

 <components:ObservationEditor ExclusiveDataProviderID="Binding DataProviderID" />

发生在 ObservationEditor 的 DC 中,而不是父控件的 DC (ObservationEditorHost)。

【讨论】:

主机页的数据上下文在主机页的构造函数中设置。您是说主机页面以某种方式继承了控件的数据联系人?我可以想象相反的情况(控件继承了主机的数据上下文)但是我不明白主机页面甚至对控件的视图模型有任何了解。

以上是关于绑定错误:WPF 正在寻找错误对象的属性的主要内容,如果未能解决你的问题,请参考以下文章

找不到WPF绑定属性

C#WPF:从SourceSafe恢复项目后获取自定义绑定错误(转换器属性未知)

如何创建静态可绑定属性描述对象

WPF 中TextBox 增加输入检测,错误提示

WPF MVVM 绑定错误

无法数据绑定滑块 WPF 的值 [重复]