代码之家  ›  专栏  ›  技术社区  ›  Grant Crofton

WPF:设置绑定在XAML中不起作用的用户控件的DataContext

  •  5
  • Grant Crofton  · 技术社区  · 14 年前

    我试图让我的第一个WPF应用程序使用MVVM,我遇到了一个小的绑定问题。

    设置是,我有一个视图&viewModel,它保存用户详细信息(父视图),为了尽量保持简单,我将该视图的一部分放入一个单独的视图&viewModel(子视图)。子视图定义为用户控件。

    class ParentViewModel: INotifyPropertyChanged
    {
        public ChildViewModel childViewModel { get; set; }
        //...
    }
    

    在父视图(其DataContext设置为ParentViewModel)的XAML中,我尝试按如下方式设置子视图的DataContext:

    <views:ChildView 
        x:Name="ChildView"
        DataContext="{Binding childViewModel}"/>
    

    但是,这不起作用。子视图的DataContext设置为与父视图相同的DataContext(即ParentViewModel),就好像我根本没有设置它一样。我还尝试在子视图本身中设置DataContext,但这也不起作用:

    <UserControl x:Class="DietRecorder.Client.View.ChildView"
        DataContext="childViewModel"
    

    我找到了一些办法来解决这个问题。在子视图中,我可以通过在路径中包含ChildViewModel来绑定所有内容:

    <SomeControl Visibility="{Binding Path=childViewModel.IsVisible}">
    

    parentView.Show();
    parentView.ChildView.DataContext = parentViewModel.childViewModel;
    

    这段代码也让我感到不安,什么都与LOD冲突。

    似乎问题出在DataContext上——我可以在子对象中绑定其他东西,例如我试图将FontSize绑定到int属性来测试它:

    <views:ChildView 
        x:Name="ChildView"
        FontSize="{Binding Path=someVal}"/>
    

    而且效果很好。

    但我确信绑定DataContext应该可以工作——我见过类似的例子。我有没有漏掉一些显而易见的东西?这是不是有什么原因不起作用?有拼写错误吗?(为了你的利益,我把东西改名了,所以你无论如何也帮不了我)。

    编辑

    <视图:ChildView
    x: Name=“儿童视图”
    DataContext={Binding childViewModel}/>
    

    我不知道为什么我不能让它开始工作,或者我可能已经改变了使它工作。也许这是一个像答案中所暗示的那样被改变了的问题。哦,好吧,向前,向上。。

    3 回复  |  直到 14 年前
        1
  •  2
  •   LBugnion    14 年前

    我怀疑这是因为childViewModel属性没有引发PropertyChanged事件。当对绑定求值时,此属性可能为空(在这种情况下,DataContext将返回到父级的属性)。稍后实例化childViewModel时,不会引发PropertyChanged事件,也不会通知绑定现在有DataContext。

    尝试在childViewModel属性中引发PropertyChanged事件。

    劳伦特

        2
  •  2
  •   NickN    13 年前

    这不是问题的答案,但在同样的情况下可能会帮助其他人。

    parentView.ChildView.DataContext = parentViewModel.childViewModel;
    

    方法起作用了(虽然我发现它在Show()之前就起作用了),但是它和最初的提问者有同样的疑虑,所以尝试了

    DataContext="{Binding ElementName=_topLevel, Path=DataContext.childViewModel}"
    

    方法,这似乎也奏效了。但后来我又试着回到原来的代码和原来的XAML,现在它突然也工作了。这反映了最初提问者的行为,作者认为他们在某个地方犯了错误,因为XAML似乎没有明显的原因而开始工作。

    我能看到的唯一变化是,Visual Studio在设计时正在UserControl中显示示例数据,因此它在某个地方缓存了一些示例数据,这似乎使它能够工作。不幸的是,我不确定这两个变化中的哪一个导致了这种情况的发生。

        3
  •  2
  •   stema Arun Mohan    11 年前

    我在找同样的东西,我找到了一种方法。基本上,我使用

    DataContext="{Binding ElementName=_topLevel, Path=DataContext.childViewModel}"
    

    在我设定的地方 x:Name="_topLevel" 在某些父控件(窗口)上。

    我试着用 RelativeSource/FindAncestor 而不是ElementName但它不起作用-但那可能是我的错。

    对我来说感觉像是一个黑客,但比绑定到顶级视图模型要好。