我正在尝试让我的第一个WPF应用程序使用MVVM,我遇到了一个小小的绑定问题.
设置是我有一个视图&viewModel,它保存用户详细信息(父级),并尝试保持简单,我将该视图的一部分放入一个单独的视图和viewModel(子).子视图定义为UserControl.
我遇到的问题是如何设置子视图的DataContext(UserControl).我的父ViewModel有一个公开子ViewModel的属性,如下所示:
class ParentViewModel: INotifyPropertyChanged
{
public ChildViewModel childViewModel { get; set; }
//...
}
Run Code Online (Sandbox Code Playgroud)
在我的父视图的XAML中(将其DataContext设置为ParentViewModel),我尝试设置子视图的DataContext,如下所示:
<views:ChildView
x:Name="ChildView"
DataContext="{Binding childViewModel}"/>
Run Code Online (Sandbox Code Playgroud)
但是,这不起作用.子视图的DataContext设置为与父视图(即ParentViewModel)相同的DataContext,就像我根本没有设置它一样.我也尝试在子视图本身设置DataContext,这也不起作用:
<UserControl x:Class="DietRecorder.Client.View.ChildView"
DataContext="childViewModel"
Run Code Online (Sandbox Code Playgroud)
我找到了几种解决方法.在子视图中,我可以通过在路径中包含ChildViewModel来绑定所有内容:
<SomeControl Visibility="{Binding Path=childViewModel.IsVisible}">
Run Code Online (Sandbox Code Playgroud)
但我不希望子视图对层次结构有这种意识.在代码中设置DataContext也可以 - 但是,我必须在显示父视图后执行此操作,否则在调用Show()时DataContext会被覆盖:
parentView.Show();
parentView.ChildView.DataContext = parentViewModel.childViewModel;
Run Code Online (Sandbox Code Playgroud)
此代码也让我感到不安,LOD违规等等.
这只是DataContext似乎是问题 - 我可以绑定孩子中的其他东西,例如我尝试将FontSize绑定到int属性只是为了测试它:
<views:ChildView
x:Name="ChildView"
FontSize="{Binding Path=someVal}"/>
Run Code Online (Sandbox Code Playgroud)
这很好.
但我确信DataContext的绑定应该起作用 - 我已经看到了类似的这种事情的例子.我错过了一些明显的东西吗?有什么理由不行吗?某处有拼写错误吗?(为了你的利益我改名了,所以无论如何你都无法帮助我).
欢迎任何想法.
编辑
再次回顾这段代码,似乎我在某个地方犯了一个错误,因为父视图中的以下XAML现在似乎有效:
<views:ChildView
x:Name="ChildView"
DataContext="{Binding childViewModel}"/>
Run Code Online (Sandbox Code Playgroud)
我不确定为什么我不能让它最初工作,或者我可能已经改变它以使其工作.也许就像其中一个答案所暗示的那样是INotifyPropertyChanged问题.哦,好吧,向上和向上..
我怀疑这是因为 childViewModel 属性没有引发 PropertyChanged 事件。当评估绑定时,该属性可能为 null(在这种情况下,DataContext 将回退到父级的属性)。当稍后实例化 childViewModel 时,不会引发 PropertyChanged 事件,并且永远不会通知绑定现在存在 DataContext。
尝试在 childViewModel 属性中引发 PropertyChanged 事件。
干杯,劳伦特