Dot-Net

在 WPF 中,如何從包含的 ListBox 的 DataTemplate 內部數據綁定到 Window DataContext?

  • January 8, 2017

我有一個 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"/>

引用自:https://stackoverflow.com/questions/1959626