我正在尝试遵循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();
}
这是我的MainViewModel
(ViewModelBase
来自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?
答案 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
对象作为来源(例如,使用DataContext
或ElementName
属性Source
1}})。
绑定引擎还指出,当前Binding
对象的类型为DataContext
,而不是类型Project
。事实是,你应该让你对代码产生怀疑。
第二行只是重复信息:MainViewModel
(或此邮件中的DataContext
)是DataItem
类型的对象,我们正试图获取其属性Project
(显然不可能,因为这个属性不存在)。
第三行显示了您的CurrentProject
目标:它是Binding
类型的对象,其属性名为ProjectControl
(类型Project
)
总结:绑定引擎正在处理的视图模型不是您认为自己绑定的视图模型。对此只有一种解释:在某处,有一些代码或另一个Project
将视图的Binding
设置为DataContext
类型的对象。
正如您在评论中提到的,您已在代码中找到了它。