2012-02-22 14 views
50

Estoy intentando vincular una lista de valores de cadena a un cuadro de lista para que sus valores se enumeren línea por línea. En este momento yo uso esto:¿Cómo puedo vincular los datos una lista de cadenas a un ListBox en WPF/WP7?

<ListBox Margin="20" ItemsSource="{Binding Path=PersonNames}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding Path=Id}"></TextBlock> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

Pero no sé lo que debo poner en el bloque de texto, en lugar de Id, ya que son todos los valores de cadena, no clases personalizadas.

También se queja de no tener que encontrar PersonNames cuando lo tengo dentro de MainPage, como MainPage.PersonNames.

puse el contexto de datos a:

DataContext="{Binding RelativeSource={RelativeSource Self}}" 

lo estoy haciendo mal?

Respuesta

111

Si en pocas palabras que su ItemsSource se une de esta manera:

YourListBox.ItemsSource = new List<String> { "One", "Two", "Three" }; 

Su XAML debe verse como:

<ListBox Margin="20" Name="YourListBox"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding}" /> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

Actualización:

Esta es una solución cuando se utiliza un DataContext. Siguiente código es el modelo de vista se le pasa a la DataContext de la página y la configuración de la DataContext:

public class MyViewModel 
{ 
    public List<String> Items 
    { 
     get { return new List<String> { "One", "Two", "Three" }; } 
    } 
} 

//This can be done in the Loaded event of the page: 
DataContext = new MyViewModel(); 

Su XAML ahora se ve así:

<ListBox Margin="20" ItemsSource="{Binding Items}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding}" /> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

La ventaja de este enfoque es que puede poner muchas más propiedades u objetos complejos en la clase MyViewModel y extraerlos en XAML. Por ejemplo, para pasar de una lista de objetos Persona:

public class ViewModel 
{ 
    public List<Person> Items 
    { 
     get 
     { 
      return new List<Person> 
      { 
       new Person { Name = "P1", Age = 1 }, 
       new Person { Name = "P2", Age = 2 } 
      }; 
     } 
    } 
} 

public class Person 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
} 

Y el XAML:

<ListBox Margin="20" ItemsSource="{Binding Items}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding Path=Name}" /> 
       <TextBlock Text="{Binding Path=Age}" /> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

Espero que esto ayude!:)

+1

Gracias, YourListBox me confunde. ¿Es el nombre del control? ¿Tienes que usar la primera línea en el código para que el xaml funcione? –

+1

Eso fue un error tipográfico, de hecho es el Nombre del Control. También puede vincular los elementos a través de un DataContext en su página o a través de Recursos. El enlace que di fue para propósitos de demostración. :) – Abbas

+0

Gracias, ¿pueden darme un ejemplo para DataContext? Me está costando entenderlo. –

8

Si la fuente de artículos es enumerable As String-entradas, utilice la siguiente:

<TextBlock Text="{Binding}"></TextBlock> 

Puede utilizar esta sintaxis en cualquier objeto. Generalmente, el método ToString() se llamará para obtener el valor. Esto es en muchos casos muy útil. Pero ten cuidado de que no se produzca ninguna notificación de cambio.

+0

Gracias, voy a tratar este pero todavía estoy teniendo un problema con la parte vinculante donde se queja de no encontrar PersonNames en xaml. –

+0

+1 para editar y proporcionar la información de -toString – mindandmedia

+0

@Joan Venge: El problema vinculante es otro problema y no se explica rápidamente en un comentario. Supongo que el DataContext de su UserControl o ventana no está configurado en la instancia de PersonNames-exposing. Si se declara en la ventana o en UserControl, puede agregar una solución rápida al enlace dentro del enlace {Binding PersonNames, RelativeSource = {RelativeSource Mode = FindAncestor, AncestorType = Window}} donde debe reemplazar "Window" por "UserControl". "si su ListBox está dentro de un UserControl. Eche un vistazo a algunas publicaciones sobre DataContext y MVVM, esto lo ayudará a comprender el DataContext – HCL

10

Usted nos debe mostrar el código para PersonNames, y no estoy seguro, entiendo su pregunta, pero tal vez usted quiera unirse de esta manera:

<TextBlock Text="{Binding Path=.}"/> 

o

<TextBlock Text="{Binding"} /> 

Este se unirá al elemento actual en la lista. (Asumiendo PersonNames es una lista de cadenas). De lo contrario, verá el nombre de la clase en la lista

+3

. Se requiere 'Path = .' para enlaces bidireccionales – Dani

1

Puede hacerlo sin tener que definir explícitamente el control TextBlock como parte de su ListBox (a menos que desee un mejor formateo). El truco para conseguir la unión de gatillo está utilizando un ObservableCollection<string> en lugar de List<string>

Window1.xaml

<ListView Width="250" Height="50" ItemsSource="{Binding MyListViewBinding}"/> 

Window1.xaml.cs

public Window1() 
{ 
    InitializeComponent(); 
    DataContext = this; 

    // Need to initialize this, otherwise you get a null exception 
    MyListViewBinding = new ObservableCollection<string>(); 
} 

public ObservableCollection<string> MyListViewBinding { get; set; } 

// Add an item to the list   
private void Button_Click_Add(object sender, RoutedEventArgs e) 
{ 
    // Custom control for entering a single string 
    SingleEntryDialog _Dlg = new SingleEntryDialog(); 

    // OutputBox is a string property of the custom control 
    if ((bool)_Dlg.ShowDialog()) 
     MyListViewBinding.Add(_Dlg.OutputBox.Trim()); 
} 
Cuestiones relacionadas