2010-01-27 32 views
6

Dado que se trata de WPF, puede parecer mucho código, pero no se asuste, la pregunta es realmente simple.WPF: Configuración de ItemSource en XAML contra código subyacente

tengo el siguiente 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> 

tengo este código subyacente:

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 dejo el comunicado Hello.ItemSource = AllRoles comentado, la cuadrícula muestra nada. Cuando lo vuelvo a colocar, muestra lo correcto. ¿Por qué es esto?

Respuesta

15

Este:

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

significa "Enlazar ItemsSource a la propiedad this.DataContext.AllRoles" donde this es el elemento actual.

Hello.ItemsSource = AllRoles; 

significa "Enlazar ItemsSource a un ObservableCollection<T> llena de papeles", lo que directamente lo que estaba tratando de hacer originalmente.

Hay una serie de formas de hacerlo en xaml. Aquí hay uno:

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

y en el xaml

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

O, alternativamente, que podría hacer AllRoles una propiedad pública de la ventana

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

y luego usar un RelativeSource a dile al enlace que suba el árbol lógico a la ventana

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

Lo que significa "Mira mi ascendencia hasta que encuentres una ventana, luego busca una propiedad pública en la ventana llamada AllRoles".

Pero la mejor manera de hacerlo es omitiendo por completo el código de frigging y use el MVVM pattern., sugiero que si está aprendiendo salte directamente al patrón de MVVM. La curva de aprendizaje es empinada, pero aprendes todo sobre el enlace y los comandos, y sobre las cosas importantes y geniales sobre WPF.

0

Cuando se vincula a una fuente de datos en WPF, está buscando una propiedad del contexto de datos de Windows llamada "AllRoles". Consulte el patrón Model-View-ViewModel para obtener más información sobre el enlace de datos en xaml. http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

Cuestiones relacionadas