2010-01-27 60 views
6

由于这是WPF,它可能看起来像很多代码,但不要害怕,问题很简单!WPF:在XAML中设置ItemSource与代码隐藏

我有以下XAML:

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:hax="clr-namespace:hax" x:Class="hax.MainWindow" 
    x:Name="Window" Title="Haxalot" Width="640" Height="280"> 

    <Grid x:Name="LayoutRoot"> 
     <ListView ItemsSource="{Binding AllRoles}" Name="Hello"> 
      <ListView.View> 
       <GridView> 
        <GridViewColumn Header="Name" 
         DisplayMemberBinding="{Binding Path=FullName}"/> 
        <GridViewColumn Header="Role" 
         DisplayMemberBinding="{Binding Path=RoleDescription}"/> 
       </GridView> 
      </ListView.View> 
     </ListView> 
    </Grid> 
</Window> 

我有这样的代码背后:

using System.Collections.ObjectModel; 
using System.Windows; 

namespace hax 
{ 

    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 

     public ObservableCollection<Role> AllRoles { get { return m_AllRoles; } set { m_AllRoles = value; } } 
     private ObservableCollection<Role> m_AllRoles = new ObservableCollection<Role>(); 

     public MainWindow() 
     { 
      this.InitializeComponent(); 

      AllRoles.Add(new Role("John", "Manager")); 
      AllRoles.Add(new Role("Anne", "Trainee")); 
      // Hello.ItemsSource = AllRoles; // NOTE THIS ONE! 
     } 
    } 
} 

如果我离开注释掉声明Hello.ItemSource = AllRoles,网格显示什么。当我把它放回去时,它显示正确的东西。为什么是这样?

回答

15

此:

<ListView ItemsSource="{Binding AllRoles}" Name="Hello"> 

意味着 “绑定ItemsSource到属性this.DataContext.AllRoles”,其中this是当前元素。

Hello.ItemsSource = AllRoles; 

的意思是“绑定ItemsSourceObservableCollection<T>充分的角色”,直接做了什么你试图做的最初。

有许多方法可以在xaml中执行此操作。这里有一个:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     this.InitializeComponent(); 
     var allRoles = new ObservableCollection<Role>() 
     allRoles.Add(new Role("John", "Manager")); 
     allRoles.Add(new Role("Anne", "Trainee")); 
     this.DataContext = allRoles; 
    } 
} 

,并在XAML

<ListView ItemsSource="{Binding}" Name="Hello"> 

,或者你可以做AllRoles窗口的公共属性

public partial class MainWindow : Window 
{ 
    public ObservableCollection<Role> AllRoles {get;private set;} 
    public MainWindow() 
    { 
     this.InitializeComponent(); 
     var allRoles = new ObservableCollection<Role>() 
     allRoles.Add(new Role("John", "Manager")); 
     allRoles.Add(new Role("Anne", "Trainee")); 
     this.AllRoles = allRoles; 
    } 
} 

,然后使用的RelativeSource来告诉绑定走上逻辑树到窗口

<ListView 
    ItemsSource="{Binding AllRoles, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" 
    Name="Hello"> 

这意味着“看看我的祖先,直到找到一个窗口,然后在名为AllRoles的窗口上查找公共属性”。

但是最好的办法是完全跳过严格的代码隐藏,并使用MVVM pattern.如果你知道你直接跳到MVVM模式,我建议你这样做。学习曲线非常陡峭,但您可以了解绑定和命令的所有信息,以及有关WPF的重要,酷炫的内容。