Binding error: WPF is looking for property on wrong object

Binding error: WPF is looking for property on wrong object

我有一个名为 ObservationEditorHost 的用户控件,它(令人惊讶地)充当另一个名为 ObservationEditor 的用户控件的主机页面。 我在输出 window 和 ObservationEditorHost 的 XAML 中收到绑定错误,ObservationEditor 的实例带有下划线并且工具顶部显示 "Object reference not set to an instance of an object".

输出中的错误信息window是:

System.Windows.Data Error: 40 : BindingExpression path error: 'DataProviderID' property not found on 'object' ''ObservationEditorViewModel' (HashCode=38856023)'. BindingExpression:Path=DataProviderID; DataItem='ObservationEditorViewModel' (HashCode=38856023); target element is 'ObservationEditor' (Name=''); target property is 'ExclusiveDataProviderID' (type 'Int32')

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

ExclusiveDataProviderID="{Binding DataProviderID}"

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

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

鉴于上述两个参数,我不明白 how/whyWPF 正在寻找 ObservationEditorViewModel for DataProviderID,如错误消息中所述。

我已经完成的故障排除:

---代码---

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;
    }
}   

问题是您正在尝试使用 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)。