Привязка данных со списком - PullRequest
5 голосов
/ 31 мая 2011

У меня есть немного кода, который читает ответ json с HTTP-сервера, затем анализирует его и вставляет данные в элемент управления ListBox.

Событие, которое запускается после завершения загрузкивыглядит следующим образом:

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

Теперь, когда я делаю items.add, я предполагаю, что это просто объединение трех переменных и добавление их в один столбец в ListBox.Это работает нормально, и я вижу все 3 элемента, которые объединены и отображаются.

Я хочу отделить это и сделать его немного лучше, поэтому я создал XAML, чтобы попытаться связать переменные с текстовыми блоками.Следующее просто привязывает имя пользователя.У меня также есть общедоступный класс, который получает / устанавливает все 3 переменные.

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

При выполнении вышеизложенного ничего не отображается вообще.У меня такое ощущение, что это что-то простое?

Спасибо.

Ответы [ 2 ]

5 голосов
/ 31 мая 2011

Чтобы отобразить простую строку, ваш xaml должен выглядеть следующим образом:

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

, и вы должны предоставить объект вместо простой строки, если вы хотите разделить свойства, чтобы они выглядели лучше.Если вы просто добавите Fid + Fusername + Fscore, вы получите простую строку.

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

Вам понадобится класс представления:

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

в вашем коде:

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;

Дополнительные примечания:

  • Почему бы не привязать ObservableCollection<UserLeaderboards> прямо к списку?

Если нет причиндля преобразования в другой тип пропустите часть кода foreach и просто установите 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);
     }
}
  • Взгляните на шаблон MVVM.Если вы хотите работать с XAML, вы должны знать об этом.Это упрощает вашу работу и создает более чистый код.

  • Если вы хотите добавить функциональность редактирования или данные могут измениться, вам может потребоваться реализовать INotifyPropertyChanged в классе View.

  • Вы можете использовать вывод типа, который особенно помогает при работе с громоздкими именами классов.var list = new ObservableCollection<SomeLongTypeName>() экономит много времени на печатание и экраны.

  • Венгерская нотация заставляет меня съеживаться;)

1 голос
/ 31 мая 2011

Я думаю, что вы пропустили шаблон.Попробуйте это

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