【问题标题】:Binding error: WPF is looking for property on wrong object绑定错误:WPF 正在寻找错误对象的属性
【发布时间】: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;
    }
}   

【问题讨论】:

    标签: c# wpf xaml datacontext


    【解决方案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)。

    【讨论】:

    • 主机页的数据上下文在主机页的构造函数中设置。您是说主机页面以某种方式继承了控件的数据联系人?我可以想象相反的情况(控件继承了主机的数据上下文)但是我不明白主机页面甚至对控件的视图模型有任何了解。
    猜你喜欢
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    • 2014-01-14
    相关资源
    最近更新 更多