Dot-Net
在 WPF 中,如何從包含的 ListBox 的 DataTemplate 內部數據綁定到 Window DataContext?
我有一個 WPF 視窗,其視圖模型設置為其 DataContext,並且有一個 ListBox,其 DataTemplate 及其 ItemsSource 綁定到視圖模型,如下例所示:
查看型號:
using System.Collections.Generic; namespace Example { class Member { public string Name { get; set; } public int Age { get; set; } } class Team { private List<Member> members = new List<Member>(); public string TeamName { get; set; } public List<Member> Members { get { return members; } } } }MainWindow.xaml:
<Window x:Class="Example.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:l="clr-namespace:Example" Title="Example" Height="300" Width="300" Name="Main"> <Window.DataContext> <l:Team TeamName="The best team"> <l:Team.Members> <l:Member Name="John Doe" Age="23"/> <l:Member Name="Jane Smith" Age="20"/> <l:Member Name="Max Steel" Age="24"/> </l:Team.Members> </l:Team> </Window.DataContext> <ListBox ItemsSource="{Binding Path=Members}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=TeamName}" Margin="4"/> <TextBlock Text="{Binding Path=Name}" Margin="4"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Window>當然,Team 類的 TeamName 屬性不會顯示在 ListBox 項中,因為 LisBox 的每個項都是 List.ItemTemplate 的 DataContext,它覆蓋了 Window 的 DataContext。
問題是:如何從 ListBox 的 DataTemplate 中將數據綁定到視圖模型 (Window.DataContext) 的 TeamName 屬性?
我會將 l:Team 聲明提取到 Window.Resources 部分,並從 DataContext 和 DataTemplate 中引用它:
<Window x:Class="Example.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:l="clr-namespace:Example" Title="Example" Height="300" Width="300" Name="Main"> <Window.Resources> <l:Team x:Key="data" TeamName="The best team"> <l:Team.Members> <l:Member Name="John Doe" Age="23"/> <l:Member Name="Jane Smith" Age="20"/> <l:Member Name="Max Steel" Age="24"/> </l:Team.Members> </l:Team> <Window.Resources> <Window.DataContext> <StaticResource ResourceKey="data"/> </Window.DataContext> <ListBox ItemsSource="{Binding Path=Members}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Source={StaticResource data}, Path=TeamName}" Margin="4"/> <TextBlock Text="{Binding Path=Name}" Margin="4"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Window>
你也可以使用RelativeSource綁定,沒那麼複雜:
<TextBlock Text="{Binding Path=DataContext.TeamName, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" Margin="4"/>