2009-12-24 32 views
7

Tôi có một cửa sổ với một mô hình xem thiết lập như DataContext của WPF, và có một ListBox với một DataTemplate và ItemsSource của nó ràng buộc với mô hình điểm, như trong ví dụ sau:Trong WPF, làm thế nào để databind vào Window DataContext từ bên trong DataTemplate của một ListBox chứa?

Xem mô hình:

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> 

Tất nhiên, tài sản TeamName của lớp Đội bóng không được hiển thị trong mục ListBox vì mỗi mục tương ứng của LisBox là DataContext của List.ItemTemplate, và nó sẽ ghi đè t ông DataContext của cửa sổ.

Câu hỏi đặt ra là: Làm cách nào để tôi databind thuộc tính TeamName của mô hình chế độ xem (Window.DataContext) từ bên trong DataBox của ListBox?

Trả lời

12

tôi sẽ trích xuất các l: khai đội đến phần Window.Resources, và tham khảo nó từ bên trong DataContext và 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. Dĩ nhiên! tôi đã không nghĩ về việc chia sẻ các mô hình xem như một nguồn lực. tôi đã cố gắng làm phức tạp dindings với RelativeSources và FindAncestor không thành công. –

+0

Rất tiếc, tôi muốn bỏ phiếu bạn lên nếu tôi có đủ uy tín –

1

Tôi muốn tạo ra một mô hình xem cho một thành viên trong nhóm, với tài sản TeamName, giống như:

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<> 
} 

Sau đó XAML của bạn sẽ trông sạch sẽ như trong ví dụ của bạn. Với MVVM, bạn không cần bất kỳ thủ đoạn liên kết kỳ lạ nào trong khung nhìn. Tất cả những gì bạn cần phải có sẵn thông qua mô hình xem.

+1

. và làm thế nào tôi sẽ làm databindings ? –

14

Bạn cũng có thể sử dụng RelativeSource ràng buộc, nó không phải là phức tạp:

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

Tại sao không bạn gắn DataContext của bạn để lập nhóm, sau đó làm cho itemsource của bạn bị ràng buộc để team.members?

thường tôi chỉ định datacontext của tôi trong codebehind của tôi nhưng nó vẫn không được anydifferent cho bạn.

itemsouce = "{Binding Path =" team.Members "}

Tôi đoán thực sự là điều tương tự của nó như những gì Aviad gợi ý. Chỉ cần tôi gán DataContext trong codebehind của tôi.

Các vấn đề liên quan