创建窗口时BindingExpression路径错误(尚未绑定VM)

时间:2017-09-12 09:01:25

标签: c# wpf mvvm

我正在尝试遵循MVVM模式,但我很难将VM属性绑定到我的UserControl的依赖项属性。我不确定我的初始化流程是否完全错误,或者我错过了一个细节。

这是我的Application Startup事件处理程序:

private void Application_Startup(object sender, StartupEventArgs e)
{
    MainViewModel viewModel = new MainViewModel();
    MainWindow window = new MainWindow();
    viewModel.BindView(window);
    window.Show();
}

这是我的MainViewModelViewModelBase来自MVVM Light):

public class MainViewModel : ViewModelBase
{
    private Project m_currentProject = new Project();
    public Project CurrentProject
    {
        get { return m_currentProject; }
        private set
        {
            m_currentProject = value;
        }
    }
}

这是我的MainWindow.xaml

<Window x:Class="WST_Desktop.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WST_Desktop"
    xmlns:controls="clr-namespace:WST_Desktop.Controls"
    mc:Ignorable="d"
    Title="MainWindow" Height="540" Width="960">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>

        <controls:ProjectControl Project="{Binding Path=CurrentProject, Converter={wstd:DebugConverter}}" />
    </Grid>
</Window>

我从DataBinding Listener中获取此错误(为便于阅读而破坏了行:)

BindingExpression path error: 'CurrentProject' property not found on 'object' ''Project' (HashCode=30400195)'. 
BindingExpression:Path=CurrentProject; DataItem='Project' (HashCode=30400195); 
target element is 'ProjectControl' (Name=''); target property is 'Project' (type 'Project')

在启动处理程序中使用new MainWindow()的行报告错误。此外,我附加到绑定的DebugConverter永远不会被击中。

我想我明白MainWindow是在没有DataContext的情况下创建的(它将在下一行绑定),因此它无法绑定ViewModel的属性(当然它还不知道) )。我对么?我该如何解决这个问题?

PS 当然,ProjectControl有一个名为Project且属于正确Project类型的公共属性。

这是在Startup事件处理程序中调用的BindView方法:

public static void BindView(this ViewModelBase viewModel, Control i_control)
{
    i_control.DataContext = viewModel;
}

基本上转化为

window.DataContext = viewModel;

更多信息

我试图改变这个

<controls:ProjectControl Project="{Binding Path=CurrentProject, Converter={wstd:DebugConverter}}" />

到这个

<controls:ProjectControl DataContext="{Binding Path=CurrentProject, Converter={wstd:DebugConverter}}" />

并且错误消失了。我不确定哪一个是正确的:Project对象(我的ProjectControl的&#34; root&#34;模型对象的类型)是否应该是依赖属性还是DataContext?

2 个答案:

答案 0 :(得分:2)

这个BindView方法是什么?

试试

window.DataContext = viewModel;

而不是

viewModel.BindView(window);

编辑:好的,因为错误消息指出您正在CurrentProject类型的对象上寻找Project属性。我建议你将DataContext的{​​{1}}绑定到Grid。这应该可以解决你的问题。

要验证是否可以解决您的问题,您只需调整绑定

即可
viewmodel

并设置窗口 <Grid DataContext="{Binding ElementName=foo, Path=DataContext}"> 的名称。

答案 1 :(得分:2)

让我们看看这个绑定错误的全部内容:

  

BindingExpression路径错误:&#39; CurrentProject&#39;找不到物业   &#39;对象&#39; &#39;&#39;项目&#39; (的HashCode = 30400195)&#39 ;.
  BindingExpression:路径= CurrentProject;的DataItem =&#39;项目&#39;   (的HashCode = 30400195);
  目标元素是&#39; ProjectControl&#39; (名称=&#39;&#39);目标财产是&#39;项目&#39; (键入&#39;项目&#39;)

你可以从中获得很多信息。

首先,绑定引擎告诉您Path的{​​{1}}属性中存在错误,因为绑定引擎无法找到名为Binding的属性作为当前CurrentProject的对象。您应该知道,绑定引擎在您未明确指定其他来源时使用DataContext对象作为来源(例如,使用DataContextElementName属性Source 1}})。

绑定引擎还指出,当前Binding对象的类型为DataContext,而不是类型Project。事实是,你应该让你对代码产生怀疑。

第二行只是重复信息:MainViewModel(或此邮件中的DataContext)是DataItem类型的对象,我们正试图获取其属性Project(显然不可能,因为这个属性不存在)。

第三行显示了您的CurrentProject目标:它是Binding类型的对象,其属性名为ProjectControl(类型Project

总结:绑定引擎正在处理的视图模型不是您认为自己绑定的视图模型。对此只有一种解释:在某处,有一些代码或另一个Project将视图的Binding设置为DataContext类型的对象。

正如您在评论中提到的,您已在代码中找到了它。