2011-05-31 10 views
5

Tengo un poco de código que lee una respuesta json de un servidor HTTP, luego lo analiza e inserta los datos en un control ListBox.Enlace de datos con un cuadro de lista

El evento que disparan cuando se complete la descarga es la siguiente:

void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) 
{ 
    DataContractJsonSerializer ser = null; 

    try 
    { 
     ser = 
     new DataContractJsonSerializer(typeof(ObservableCollection<UserLeaderboards>)); 

     ObservableCollection<UserLeaderboards> users = 
      ser.ReadObject(e.Result) as ObservableCollection<UserLeaderboards>; 

     foreach (UserLeaderboards em in users) 
     { 
      int Fid = em.id; 
      string Fusername = em.username; 
      int Fscore = em.score; 
      lstbLeaders.Items.Add(Fid + Fusername + Fscore); 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 

Ahora, cuando hago la items.add supongo que simplemente se unió a las 3 variables y agregarlo a una columna en la ListBox . Esto funciona bien y veo los 3 elementos unidos y mostrados.

Quiero separar esto y hacer que se vea un poco mejor así que he creado algunos XAML para tratar de vincular las variables a los bloques de texto. Lo siguiente es solo el enlace del nombre de usuario. También tengo una clase pública que obtiene/establece las 3 variables.

<ListBox Height="346" HorizontalAlignment="Left" Margin="5,221,0,0" 
     Name="lstbLeaders" VerticalAlignment="Top" Width="446"> 
    <DataTemplate>        
     <TextBlock Text="{Binding Source=Fusername}" />       
    </DataTemplate> 
</ListBox> 

Al ejecutar lo anterior, no aparece nada en absoluto. Tengo la sensación de que es algo simple

Gracias.

Respuesta

5

Para mostrar una cadena sencilla su xaml debería tener este aspecto:

<ListBox Height="346" HorizontalAlignment="Left" Margin="5,221,0,0" 
     Name="lstbLeaders" VerticalAlignment="Top" Width="446"> 
    <ListBox.ItemTemplate> 
     <DataTemplate>        
      <TextBlock Text="{Binding}" />       
     </DataTemplate> 
    <ListBox.ItemTemplate> 
</ListBox> 

y usted tiene que proporcionar un objeto en lugar de una cadena simple si desea dividir las propiedades de hacer se ve mejor. Si solo agrega Fid + Fusername + Fscore terminará con una cadena simple.

<ListBox Height="346" HorizontalAlignment="Left" Margin="5,221,0,0" 
     Name="lstbLeaders" VerticalAlignment="Top" Width="446"> 
    <ListBox.ItemTemplate> 
     <DataTemplate>        
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="{Binding Id}" />       
       <TextBlock Text="{Binding Name}" />       
       <TextBlock Text="{Binding Score}" />       
      </StackPanel> 
     </DataTemplate> 
    <ListBox.ItemTemplate> 
</ListBox> 

Usted necesitará una clase de vista:

public class UserView 
{ 
    public string Id {get;set;} 
    public string Name {get;set;} 
    public int Score {get;set;} 
} 

en su código detrás:

var usersList = new List<UserView>(); 

foreach (UserLeaderboards em in users) 
{ 
    int Fid = em.id; 
    string Fusername = em.username; 
    int Fscore = em.score; 
    usersList.Add(new UserView { Id = Fid, Name = Fusername, Score = Fscore}); 
} 

lstbLeaders.ItemsSource = usersList; 

Otras notas:

  • Por qué no obligar a la ObservableCollection<UserLeaderboards> direcectly a el cuadro de lista?

Si no hay ninguna razón para convertir a otro tipo de omitir la parte foreach del código y simplemente establecer lstbLeaders.ItemsSource = users;.

void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) 
{ 
    try 
    { 
     var ser = new DataContractJsonSerializer(
        typeof(ObservableCollection<UserLeaderboards>)); 

     var users = ser.ReadObject(e.Result) 
         as ObservableCollection<UserLeaderboards>; 

     lstbLeaders.ItemsSource = users; 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 
  • mirada Tome el patrón MVVM. Si quieres trabajar con XAML, debes saberlo. Simplifica tu trabajo y crea un código más limpio.

  • Si desea agregar la funcionalidad de edición o los datos pueden cambiar, es posible que deba implementar INotifyPropertyChanged en la clase View.

  • Puede usar la inferencia de tipo, que especialmente ayuda cuando se trabaja con nombres de clases engorrosos. var list = new ObservableCollection<SomeLongTypeName>() ahorra mucho tipeo y estado de la pantalla.me hace temblar

  • notación húngara;)

+0

no hay ninguna razón para que no se vincule directamente al listbox, Mi conocimiento no es muy alto del lado XAML de las cosas. He editado mi proyecto con un simple lstbLeaders.ItemsSource = users; Manteniendo la clase userview según tu publicación. Ahora obtengo 00 en cada línea. – Nathan

+0

¿Cómo es tu XAML? Compruebe (utilizando el depurador) si los valores de las colecciones están configurados o si la deserialización introduce un error. Agregué un nuevo fragmento de código a mi respuesta para adaptar tu código. Su XAML tendrá que vincularse a las propiedades de la clase 'UserLeaderboards' ahora:' id', 'username',' score'. – Zebi

+0

eso lo ha ordenado, gracias por su ayuda !! – Nathan

1

Creo que te has perdido el ItemTemplate. Prueba este

<ListBox Height="346" HorizontalAlignment="Left" Margin="5,221,0,0" Name="lstbLeaders"   VerticalAlignment="Top" Width="446"> 
    <ListBox.ItemTemplate> 
     <DataTemplate>         
      <TextBlock Text="{Binding Source=Fusername}" />      
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 
+0

He añadido las pestañas itemtemplate y todavía no está mostrando nada. – Nathan

+0

¿También intentó configurar ItemSource [lstbLeaders.Itemsource = List ()) en Code Behind? Tal vez la fuente es lo mismo que el fondo. :-) – kanchirk

Cuestiones relacionadas