【发布时间】:2015-04-30 05:44:33
【问题描述】:
我有一种情况,父 DataContext 与子 DataContext 不同,我想从子中的绑定访问父 DataContext。这可以使用详细的 RelativeSource 来完成,如下所示:
<Button Content="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MainWindow}}, Path=DataContext.Bar}"/>
我想找到一种更简洁的方式来引用父级的 DataContext。有没有办法,例如,父级可以通过父级中定义的 Resource 公开对它的 DataContext (或它的任何属性)的引用?理想情况下,孩子的绑定将如下所示(请原谅我使用 StaticResource 作为示例)。
<Button Path=Bar, Content="{StaticResource parentDataContextReference}"/>
理想情况下,避免代码隐藏,但对该解决方案持开放态度。一个人为的例子:
MainWindow.xaml
<Window x:Class="BindingTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:BindingTest"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<x:ArrayExtension x:Key="children" Type="{x:Type local:ChildViewModel}">
<local:ChildViewModel Name="Child 1"/>
<local:ChildViewModel Name="Child 2"/>
</x:ArrayExtension>
</Window.Resources>
<StackPanel>
<Button Content="{Binding Foo}" Height="20" Width="60"></Button>
<ListView ItemsSource="{StaticResource children}">
<ListView.ItemTemplate>
<DataTemplate>
<local:ChildView/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Window>
MainWindow.xaml.cs
namespace BindingTest
{
public class MainViewModel
{
public string Foo { get; set; }
public string Bar { get; set; }
public MainViewModel()
{
Foo = "Foo";
Bar = "Bar";
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel();
}
}
}
ChildView.xaml
<UserControl x:Class="BindingTest.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:BindingTest"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel Orientation="Horizontal">
<Button Content="{Binding Name}"/>
<Button Content="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MainWindow}}, Path=DataContext.Bar}"/>
</StackPanel>
</UserControl>
ChildView.xaml.cs
namespace BindingTest
{
public class ChildViewModel
{
public string Name { get; set; }
public ChildViewModel()
{
Name = "Undefined";
}
}
public partial class ChildView : UserControl
{
public ChildView()
{
InitializeComponent();
}
}
}
【问题讨论】:
-
你为什么不喜欢 relativesource 的东西?
-
<Button Content="{Binding Bar.SomeBarProperty}"/>怎么样?不需要其他任何东西。 -
@blindmeis - 对于一次性情况来说很好,但我希望有一种更简洁/可读/不易出错的方式来引用父级 DataContext 中的某些内容。如果有某种别名我可以设置它会是一半的字符和更简单的语法。
-
@Clemens - 抱歉,我不明白这个建议。 Bar 不是 ChildView.DataContext 包含的属性。你的意思是如果 ChildViewModel 有对 MainViewModel 的引用会怎样?
-
在RelativeSource 示例中,您将Button 的内容绑定到MainWindow 的DataContext 中的
Bar属性。您不需要这样做,因为 DataContext 被继承到 MainWindow 的子元素。绑定可以写成Content="{Binding Bar}"。
标签: c# wpf xaml resourcedictionary