2010-01-27 4 views
6

Étant donné que c'est WPF, cela peut ressembler à beaucoup de code, mais ne soyez pas effrayé, la question est vraiment simple!WPF: Définition de ItemSource en XAML par rapport au code

je le XAML suivant:

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

J'ai ce code-behind:

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

Si je laisse la déclaration Hello.ItemSource = AllRoles commentaire, la grille affiche rien. Quand je le remets, il affiche la bonne chose. Pourquoi est-ce?

Répondre

15

Ce:

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

signifie "Bind ItemsSource à la propriété this.DataContext.AllRoles" où this est l'élément courant.

Hello.ItemsSource = AllRoles; 

signifie « Bind ItemsSource à une pleine ObservableCollection<T> des rôles », qui ne directement ce que vous essayez de faire à l'origine.

Il existe un certain nombre de façons de le faire dans xaml. En voici un:

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

et dans le XAML

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

ou bien que vous pouvez faire AllRoles une propriété publique de la fenêtre

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

puis utiliser un RelativeSource à dire à la liaison de remonter l'arbre logique à la fenêtre

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

Ce qui signifie «Regardez mon ascendance jusqu'à ce que vous trouviez une fenêtre, puis cherchez une propriété publique dans la fenêtre appelée AllRoles».

Mais la meilleure façon de le faire est d'ignorer complètement le code du frigging et d'utiliser le MVVM pattern.. Je vous suggère si vous apprenez que vous passez directement au modèle MVVM. La courbe d'apprentissage est raide, mais vous apprendrez tout sur la liaison et les commandes et les choses importantes et intéressantes sur WPF.

0

Lorsque vous liez une source de données dans WPF, elle recherche une propriété du contexte de données de votre fenêtre appelée "AllRoles". Découvrez le modèle Model-View-ViewModel pour en savoir plus sur la liaison de données dans xaml. http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

Questions connexes