在 WPF 中绑定到 parent window 的视图模型时,AncestorLevel 不起作用
AncestorLevel not working when binding to the view model of parent window in WPF
MainWindow 绑定到 MainViewModel
,其余的都绑定到 ChildViewModel
,这是 MainViewModel
的 属性。现在最里面的childwindow绑定了ChildViewModel
,我想绑定一个属性到MainViewModel
.
我正在使用以下代码:
此处 Converter
的第一个值绑定到 ChildViewModel
中的 属性 C
并且有效。我试图将第二个值绑定到 属性 到 MainWindow
(MainViewModel
) 的 DataContext 但没有成功。
<MultiBinding Converter="{StaticResource UnitConverter}">
<Binding Path="C"/>
<Binding RelativeSource="{RelativeSource FindAncestor,
AncestorType={x:Type Window}, AncestorLevel=2}"
Path="DataContext.CurrentTargetUnit"/>
</MultiBinding>
--- Main Window -------------------------------------------
- ----- User Control 1 ------------------------------- -
- - ---- User Control 2-------------------------- - -
- - - ------ Child Window 1 ---------------- - - -
- - - - ----- Child Window 2 ---------- - - - -
- - - - - - - - - -
- - - - - [Bind to MainViewModel] - - - - -
- - - - - - - - - -
- - - - ------------------------------- - - - -
- - - -------------------------------------- - - -
- - --------------------------------------------- - -
- ---------------------------------------------------- -
-----------------------------------------------------------
更新:
我最好的猜测是只能绑定到 parent window 并且不能高于此。也许最上面的 window 不在可视化树中?
在 ChildViewModel
上创建一个 属性,它是对 MainViewModel
的引用 link。在子 VM 实例化后,link 它到 MainViewModel
。然后内部 windows/controls 可以通过引用上述 ChildViewModel
属性 到主虚拟机来到达 MainViewModel
。
在用户控件 1 和 2 上创建主视图模型类型的依赖项 属性,例如:
// <summary>
/// Holds the parent VM here.
/// </summary>
public MainVM ParentVM
{
get { return GetValue(ParentVMProperty) as MainVM; }
set { SetValue(ParentVMProperty, value); }
}
/// <summary>
/// Identifies the ParentVM dependency property.
/// </summary>
public static readonly System.Windows.DependencyProperty ParentVMProperty =
System.Windows.DependencyProperty.Register(
"ParentVM",
typeof(MainVM),
typeof({Insert Control1 or 2 class type here}),
new System.Windows.PropertyMetadata(null, OnParentVMPropertyChanged));
/// <summary>
/// ParentVMProperty property changed handler.
/// </summary>
/// <param name="d">BeginRandom that changed its ParentVM.</param>
/// <param name="e">Event arguments.</param>
private static void OnParentVMPropertyChanged(System.Windows.DependencyObject d, System.Windows.DependencyPropertyChangedEventArgs e)
{
var source = d as {Insert Control1 or 2 class type here};
MainVM value = e.NewValue as MainVM;
}
由于每个 window 都将有一个对 MainWindowVM 可用的引用,您所要做的就是指向当前 window 的 ParentVM
属性 的路径。
请注意,为了创建控件的依赖属性,我使用了为 Silverlight 编写的方便的片段,但是所有这些 都可以在 WPF 中工作:
MainWindow 绑定到 MainViewModel
,其余的都绑定到 ChildViewModel
,这是 MainViewModel
的 属性。现在最里面的childwindow绑定了ChildViewModel
,我想绑定一个属性到MainViewModel
.
我正在使用以下代码:
此处 Converter
的第一个值绑定到 ChildViewModel
中的 属性 C
并且有效。我试图将第二个值绑定到 属性 到 MainWindow
(MainViewModel
) 的 DataContext 但没有成功。
<MultiBinding Converter="{StaticResource UnitConverter}">
<Binding Path="C"/>
<Binding RelativeSource="{RelativeSource FindAncestor,
AncestorType={x:Type Window}, AncestorLevel=2}"
Path="DataContext.CurrentTargetUnit"/>
</MultiBinding>
--- Main Window -------------------------------------------
- ----- User Control 1 ------------------------------- -
- - ---- User Control 2-------------------------- - -
- - - ------ Child Window 1 ---------------- - - -
- - - - ----- Child Window 2 ---------- - - - -
- - - - - - - - - -
- - - - - [Bind to MainViewModel] - - - - -
- - - - - - - - - -
- - - - ------------------------------- - - - -
- - - -------------------------------------- - - -
- - --------------------------------------------- - -
- ---------------------------------------------------- -
-----------------------------------------------------------
更新:
我最好的猜测是只能绑定到 parent window 并且不能高于此。也许最上面的 window 不在可视化树中?
在 ChildViewModel
上创建一个 属性,它是对 MainViewModel
的引用 link。在子 VM 实例化后,link 它到 MainViewModel
。然后内部 windows/controls 可以通过引用上述 ChildViewModel
属性 到主虚拟机来到达 MainViewModel
。
在用户控件 1 和 2 上创建主视图模型类型的依赖项 属性,例如:
// <summary>
/// Holds the parent VM here.
/// </summary>
public MainVM ParentVM
{
get { return GetValue(ParentVMProperty) as MainVM; }
set { SetValue(ParentVMProperty, value); }
}
/// <summary>
/// Identifies the ParentVM dependency property.
/// </summary>
public static readonly System.Windows.DependencyProperty ParentVMProperty =
System.Windows.DependencyProperty.Register(
"ParentVM",
typeof(MainVM),
typeof({Insert Control1 or 2 class type here}),
new System.Windows.PropertyMetadata(null, OnParentVMPropertyChanged));
/// <summary>
/// ParentVMProperty property changed handler.
/// </summary>
/// <param name="d">BeginRandom that changed its ParentVM.</param>
/// <param name="e">Event arguments.</param>
private static void OnParentVMPropertyChanged(System.Windows.DependencyObject d, System.Windows.DependencyPropertyChangedEventArgs e)
{
var source = d as {Insert Control1 or 2 class type here};
MainVM value = e.NewValue as MainVM;
}
由于每个 window 都将有一个对 MainWindowVM 可用的引用,您所要做的就是指向当前 window 的 ParentVM
属性 的路径。
请注意,为了创建控件的依赖属性,我使用了为 Silverlight 编写的方便的片段,但是所有这些 都可以在 WPF 中工作: