2011-05-31 20 views
5

Ho un po 'di codice che legge una risposta JSON da un server HTTP, quindi analizza questo e inserisce i dati in un controllo ListBox.Associazione di dati con una listbox

L'evento sparo quando il download è completato è il seguente:

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

Ora, quando faccio il items.add presumo che è solo unendo le 3 variabili e l'aggiunta di una colonna nella ListBox . Funziona bene e vedo tutti e 3 gli articoli unificati e visualizzati.

Voglio separare questo e renderlo un po 'più bello, quindi ho creato un po' di XAML per provare e associare le variabili ai blocchi di testo. Quello che segue è solo il nome utente vincolante. Ho anche una classe pubblica che ottiene/imposta tutte e 3 le variabili.

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

Quando si esegue quanto sopra, non viene visualizzato nulla. Ho la sensazione che sia qualcosa di semplice?

Grazie.

risposta

5

Per visualizzare una semplice stringa vostro XAML dovrebbe assomigliare a questa:

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

ed è necessario fornire un oggetto invece di una stringa semplice se si desidera dividere le proprietà per fare sembra più bello. Se si aggiunge solo Fid + Fusername + Fscore si finirà con una stringa semplice.

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

Avrete bisogno di una classe di visualizzazione:

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

nel codice dietro:

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; 

Ulteriori note:

  • Perché non vincolano il ObservableCollection<UserLeaderboards> direcectly a la casella di riepilogo?

Se non v'è alcun motivo per convertire in un altro tipo di saltare la parte foreach del codice e semplicemente impostare 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); 
    } 
} 
  • Prendere un'occhiata al modello MVVM. Se vuoi lavorare con XAML dovresti saperlo. Semplifica il tuo lavoro e crea un codice più pulito.

  • Se si desidera aggiungere funzionalità di modifica o dati, è possibile che sia necessario implementare INotifyPropertyChanged nella classe View.

  • È possibile utilizzare l'inferenza di tipo che è particolarmente utile quando si utilizzano nomi di classe ingombranti. var list = new ObservableCollection<SomeLongTypeName>() consente di risparmiare molto spazio sulla digitazione e sullo schermo.

  • ungherese notazione mi fa rabbrividire;)

+0

non c'è motivo per non legare direttamente alla listbox, la mia conoscenza non è molto alta sul lato XAML delle cose. Ho modificato il mio progetto con un semplice lstbLeaders.ItemsSource = utenti; Mantenere la classe userview secondo il tuo post. Ora ottengo solo 00 su ogni riga. – Nathan

+0

Che aspetto ha XAML? Controllare (usando il debugger) se i valori delle collezioni sono impostati o se la deserializzazione introduce un errore. Ho aggiunto un nuovo snippet di codice alla mia risposta adattando il tuo codice. Il tuo XAML dovrà legarsi alle proprietà della classe 'UserLeaderboards' ora:' id', 'username',' score'. – Zebi

+0

questo è stato risolto, grazie per il vostro aiuto !! – Nathan

1

Penso che ti sia sfuggito il ItemTemplate. Prova questo

<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

ho aggiunto le schede ItemTemplate e non è ancora la visualizzazione di qualsiasi cosa. – Nathan

+0

Hai provato anche a impostare ItemSource [lstbLeaders.Itemsource = List ()) in Code Behind? Forse il carattere è lo stesso dello sfondo. :-) – kanchirk

Problemi correlati