我正在尝试让我的第一个WPF应用程序使用MVVM,我遇到了一些绑定问题。
设置是我有一个视图& viewModel保存用户详细信息(父级),并尝试保持简单我已将该视图的一部分放入单独的视图& viewModel(孩子)。子视图定义为UserControl。
我遇到的问题是如何设置子视图的DataContext(UserControl)。我的父ViewModel有一个公开子ViewModel的属性,如下所示:
class ParentViewModel: INotifyPropertyChanged
{
public ChildViewModel childViewModel { get; set; }
//...
}
在我的父视图的XAML中(将其DataContext设置为ParentViewModel),我尝试按如下方式设置子视图的DataContext:
<views:ChildView
x:Name="ChildView"
DataContext="{Binding childViewModel}"/>
然而,这不起作用。子视图的DataContext设置为与父视图(即ParentViewModel)相同的DataContext,就像我根本没有设置它一样。我也尝试在子视图中设置DataContext,这也不起作用:
<UserControl x:Class="DietRecorder.Client.View.ChildView"
DataContext="childViewModel"
我找到了几种方法。在子视图中,我可以通过在路径中包含ChildViewModel来绑定所有内容:
<SomeControl Visibility="{Binding Path=childViewModel.IsVisible}">
但我不希望子视图对层次结构具有这种级别的意识。在代码中设置DataContext也可以 - 但是,我必须在显示父视图后执行此操作,否则当我调用Show()时,DataContext会被覆盖:
parentView.Show();
parentView.ChildView.DataContext = parentViewModel.childViewModel;
这段代码也让我感到不安,LOD违规行为和所有内容。
这只是DataContext似乎是问题 - 我可以绑定孩子中的其他东西,例如我尝试将FontSize绑定到int属性只是为了测试它:
<views:ChildView
x:Name="ChildView"
FontSize="{Binding Path=someVal}"/>
这很好。
但我确信DataContext的绑定应该有效 - 我已经看到了类似的这种事情的例子。我错过了一些明显的东西吗?有什么理由不行吗?某处有拼写错误吗? (为了你的利益我改名了,所以无论如何你都无法帮助我。)
欢迎任何想法。
修改
再次查看此代码,似乎我在某个地方犯了一个错误,因为父视图中的以下XAML现在似乎有效:
<views:ChildView
x:Name="ChildView"
DataContext="{Binding childViewModel}"/>
我不确定为什么我不能让它最初工作,或者我可能已经改变它以使它工作。也许就像其中一个答案所暗示的那样是INotifyPropertyChanged问题。哦,好吧,向上和向上......
答案 0 :(得分:2)
我怀疑是因为childViewModel属性不会引发PropertyChanged事件。在评估绑定时,此属性可能为null(在这种情况下,DataContext将回退到父级的属性)。稍后实例化childViewModel时,不会引发PropertyChanged事件,并且永远不会通知绑定现在存在DataContext。
尝试在childViewModel属性中引发PropertyChanged事件。
干杯, 劳伦
答案 1 :(得分:2)
我一直在寻找同样的东西,我找到了一种方法。基本上,我使用
将子的DataContext绑定到某个父级(窗口)的DataContextDataContext="{Binding ElementName=_topLevel, Path=DataContext.childViewModel}"
我在某个父控件(窗口)上设置了x:Name="_topLevel"
。
我尝试使用RelativeSource/FindAncestor
而不是ElementName,但它没有用 - 但这可能是我的错。
感觉像是对我的黑客攻击,但比绑定到顶级视图模型更好。
答案 2 :(得分:2)
这不是问题的答案,但可能在同样的情况下帮助其他人。
我确实遇到了这个问题并发现了
parentView.ChildView.DataContext = parentViewModel.childViewModel;
方法有效(虽然我发现它在做Show()之前有效),但与原始提问者有相同的疑虑,所以尝试了
DataContext="{Binding ElementName=_topLevel, Path=DataContext.childViewModel}"
方法,似乎也有效。但后来我再次尝试回到原始代码和原始XAML,现在它突然也起作用了。这反映了原始提问者的行为,即作者认为他们在某处犯了一个错误,因为XAML似乎没有明显的原因开始工作。
我能看到的唯一变化是Visual Studio现在在设计时在UserControl中显示示例数据,因此它已经在某处缓存了一些示例数据,这似乎使它工作。不幸的是,我不确定这两次变化中的哪一次发生了。
样本数据的出现让我想知道这个问题是否与使用d:DataContext有关,我在父和子XAML文件中有这个问题,但这只是推测。