2010-01-27 10 views
6

Ponieważ jest to WPF, może wyglądać jak dużo kodu, ale nie przejmuj się, pytanie jest naprawdę proste!WPF: Ustawianie źródła pozycji w XAML a kodowanie z tyłu

Mam następujące 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> 

mam ten kod z opóźnieniem:

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

Gdybym opuścić oświadczenie Hello.ItemSource = AllRoles wykomentowane, siatka wyświetla nic. Po ponownym włożeniu wyświetla prawidłową rzecz. Dlaczego to?

Odpowiedz

15

to:

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

oznacza "Bind ItemsSource do nieruchomości this.DataContext.AllRoles" gdzie this jest obecny pierwiastek.

Hello.ItemsSource = AllRoles; 

oznacza "Bind ItemsSource do ObservableCollection<T> pełną ról", które bezpośrednio robi to, co staraliśmy się zrobić pierwotnie.

Istnieje wiele sposobów, aby to zrobić w Xaml. Oto jeden:

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

aw XAML

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

lub, alternatywnie, można zrobić AllRoles własność publiczną okna

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

a następnie użyć RelativeSource do opowiedz Wiązanie, aby podejść do drzewa logicznego do okna

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

Co oznacza "Spójrz na moje pochodzenie, dopóki nie znajdziesz okna, a następnie poszukaj publicznej nieruchomości w oknie o nazwie AllRoles".

Ale najlepszym sposobem, aby to zrobić, jest całkowite pominięcie kodu skojarzonego i skorzystanie z MVVM pattern.. Proponuję, jeśli się uczysz, że przechodzisz bezpośrednio do wzorca MVVM. Krzywa uczenia się jest stroma, ale uczysz się wszystkiego o wiązaniach i komendach oraz o ważnych, fajnych rzeczach związanych z WPF.