2009-12-24 74 views
7

我有一个WPF窗口与设置为其DataContext的视图模型,并与一个DataTemplate和其的ItemsSource列表框绑定到视图模型,如在下面的例子:在WPF中,如何从包含ListBox的DataTemplate中将数据绑定到Window DataContext?

查看模型:

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> 

当然,团队一流的TeamName属性不会因为LisBox的每一个项目是List.ItemTemplate的DataContext的显示在列表框中的项目,它将覆盖ŧ他窗口的DataContext。

问题是:如何从列表框的DataTemplate中绑定到视图模型(Window.DataContext)的TeamName属性?

回答

12

我会提取L:团队宣言到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> 
+0

+1。当然了!我没有想过将视图模型作为一个资源共享,我试图用RelativeSources和FindAncestor使事情复杂化,但没有成功。 – 2009-12-25 00:38:09

+0

糟糕,如果我有足够的声望,我会为您投票 – 2009-12-25 00:40:17

1

我想创建一个团队成员视图模型,用一个TeamName财产,是这样的:

class MemberViewModel 
{ 
    ... 
    private TeamViewModel _team; 
    public string TeamName{ get { return _team.Name; } } 
} 

class TeamViewModel 
{ 
    public List<MemberViewModel> Members { get{ ... } } 
    // You may consider using ObservableCollection<> instead of List<> 
} 

那么你的XAML看起来那样干净你的榜样。有了MVVM,你不应该在视图中需要任何特殊的绑定技巧。所有你需要的应该可以通过视图模型获得。

+1

我该如何处理数据绑定? – 2009-12-25 00:43:01

14

您还可以使用的RelativeSource约束力,但它并不复杂:

<TextBlock Text="{Binding Path=DataContext.TeamName, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" Margin="4"/> 
0

你为什么不绑定您的DataContext组队,然后使你的ItemSource势必team.members?

通常我在我的代码隐藏中分配我的datacontext,但它仍然不应该为你做任何不同的事情。

itemsouce = “{绑定路径=” team.Members“}

我想真正的同样的事情,有什么建议阿维亚德,只是我给你的datacontext在我隐藏。

相关问题