[英]Binding an element in a child View to a property of the parent ViewModel
Like the title says, I would like to bind an element in a child View to a property of the parent ViewModel. 就像标题所说,我想将子视图中的元素绑定到父ViewModel的属性。
Is there a Caliburn.Micro or default WPF XAML syntax to do this? 是否有Caliburn.Micro或默认的WPF XAML语法来执行此操作? I mean, this exact situation: to bind to parent ViewModel's property.
我的意思是,这个确切的情况:绑定到父ViewModel的属性。
Or should I try to achieve this some other way? 或者我应该尝试以其他方式实现这一目标吗? Is so, what would be the best/easiest way to do it?
是这样,最好/最简单的方法是什么?
Here is a very basic Caliburn.Micro App example: 这是一个非常基本的Caliburn.Micro App示例:
MainWindowViewModel.cs
namespace BindingToParentVMProperty.MVVM
{
public class MainWindowViewModel
{
public ChildViewModel Child { get; set; }
public string ParentName { get; set; }
public MainWindowViewModel()
{
Child = new ChildViewModel();
ParentName = "Peter Griffin";
}
}
}
MainWindowView.xaml
: MainWindowView.xaml
:
<UserControl x:Class="BindingToParentVMProperty.MVVM.MainWindowView"
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"
mc:Ignorable="d">
<Grid Width="200" Height="200">
<ContentControl Name="Child" />
</Grid>
</UserControl>
ChildViewModel.cs
: ChildViewModel.cs
:
using Caliburn.Micro;
namespace BindingToParentVMProperty.MVVM
{
public class ChildViewModel
{
public BindableCollection<GrandChildViewModel> GrandKids { get; set; }
public string ChildName { get; set; }
public ChildViewModel()
{
ChildName = "Stewie Griffin";
GrandKids = new BindableCollection<GrandChildViewModel>
{
new GrandChildViewModel {GrandChildName = "Stewie Griffin Jr."},
new GrandChildViewModel {GrandChildName = "Rupert Griffin Jr."}
};
}
}
}
ChildView.xaml
: ChildView.xaml
:
<UserControl x:Class="BindingToParentVMProperty.MVVM.ChildView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel>
<!-- need to bind to MainWindowViewModel.ParentName-->
<TextBlock Text="{Binding Path=HowToBindTo_ParentName}"/>
<ListView Name="GrandKids" />
</StackPanel>
</UserControl>
GrandChildViewModel.cs
: GrandChildViewModel.cs
:
namespace BindingToParentVMProperty.MVVM
{
public class GrandChildViewModel
{
public string GrandChildName { get; set; }
}
}
GrandChildView.xaml
: GrandChildView.xaml
:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
x:Class="BindingToParentVMProperty.MVVM.GrandChildView"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel>
<TextBlock x:Name="GrandChildName" />
<!-- need to bind to ChildViewModel.ChildName -->
<TextBlock Text="{Binding Path=HowToBindTo_ChildName}"/>
</StackPanel>
</UserControl>
It seems like the most straightforward suggestion would be to keep some record of the parent on the child ViewModel
(eg a Parent
property). 似乎最直接的建议是在子
ViewModel
上保留父级的一些记录(例如, Parent
属性)。 Since you want to have your ViewModels
tied to their respective Views
, I think it will become conceptually quite tricky if you start to bind to properties and include information from beyond the scope of the bound ViewModel
. 由于您希望将
ViewModels
绑定到各自的Views
,我认为如果您开始绑定到属性并包含超出绑定ViewModel
范围的信息,那么它在概念上将变得非常棘手。
Also, whilst it may not be of concern for the particular project you're working on, if you start including properties from other UserControls
, you're implicitly creating a links and dependencies, which may come back to inconvenience you if you wish to re-use the controls elsewhere in a non-hierarchical context. 此外,虽然您可能不关心您正在处理的特定项目,但如果您开始包含来自其他
UserControls
属性,则会隐式创建链接和依赖项,如果您希望重新启动,可能会给您带来不便 - 在非分层上下文中的其他位置使用控件。
That said, you could traverse up your UI tree to get the required DataContext
( ViewModel
) from a parent control, and bind to the desired property using existing WPF
syntax, as Kollegos
suggests, by using RelativeSource
and the AncestorType
property. 也就是说,您可以遍历UI树以从父控件获取所需的
DataContext
( ViewModel
),并使用现有的WPF
语法绑定到所需的属性,正如Kollegos
建议的那样,使用RelativeSource
和AncestorType
属性。
In your case, it might look something like this: 在您的情况下,它可能看起来像这样:
<UserControl x:Class="BindingToParentVMProperty.MVVM.ChildView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:YourProjectNamespaceContainingParentView"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel>
<!-- Set our DataContext bind to parent MainWindowViews DataContext (ViewModel) -->
<TextBlock Text="{Binding Path=ParentName}"
DataContext="{Binding RelativeSource={RelativeSource
FindAncestor, AncestorType={x:Type local:MainWindowView}},
Path=DataContext}"/>
<ListView Name="GrandKids" />
</StackPanel>
So, you can use MainWindowViewModel
for all your views, but I don't know how it work with Caliburn. 因此,您可以将
MainWindowViewModel
用于所有视图,但我不知道它如何与Caliburn一起使用。 I dont know how you use your UserControl
s, but maybe RelativeSource
can help you (you can bind to DataContext
of relative control for example). 我不知道你如何使用你的
UserControl
,但也许RelativeSource
可以帮助你(你可以绑定到相对控制的DataContext
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.