Только недавно начал знакомиться с silverlight и для примера решил написать приложение получающее через Api Вконтакте новости профиля, т.е. использовал метод newsfeed.get и столкнулся с проблемой...
Вообщем данные после api запроса newsfeed.get получаются в формате JSON следующие (пример из api документации):
Код |
{"response": {"items": [{"type":"post", "source_id":29231, "date":1289314418, "post_id":1423, "text":"Завтра в Москоу", "comments": {"count":0, "can_post":1}, "likes": {"count":0, "user_likes":0}}, {"type":"post", "source_id":100534, "date":1289314068, "post_id":4643, "text":Lorem ipsum dolor sit amet, consectetur adipiscing elit.", "comments": {"count":3, "can_post":1}, "likes": {"count":0, "user_likes":0}}], "profiles": [{"uid":29231, "first_name":"Алексей", "last_name":"Бартновский", "photo_rec":"http:\/\/cs5046.vkontakte.ru\/u29231\/e_8616f561.jpg"}, {"uid":100172, "first_name":"Алексей", "last_name":"Тройников", "photo_rec":"http:\/\/cs9911.vkontakte.ru\/u100172\/e_83e6ec58.jpg"}, {"uid":100534, "first_name":"Ксюша", "last_name":"Павлова", "photo_rec":"http:\/\/cs10089.vkontakte.ru\/u100534\/e_c3ca81b1.jpg"}], "groups": [{"gid":1, "name":"ВКонтакте API", "screen_name":"apiclub", "is_closed":0, "is_admin":1, "photo":"http:\/\/cs400.vkontakte.ru\/g00001\/e_5ba03323.jpg", "photo_medium":"http:\/\/cs400.vkontakte.ru\/g00001\/d_7bfe2183.jpg", "photo_big":"http:\/\/cs400.vkontakte.ru\/g00001\/a_9a5cd502.jpg"}]}}
|
Таким образом ответ состоит из 3 главных полей:
items - содержит массив новостей для текущего пользователя
profiles - содержит информацию о пользователях, которые находятся в списке новостей
groups - содержит информацию о группах, которые находятся в списке новостей
Для их десериализации написан класс на c#:
Код |
[DataContract] public partial class GroupsList { [DataMember(Name = "gid")] public string GroupGid { get; set; }
[DataMember(Name = "name")] public string GroupName { get; set; }
[DataMember(Name = "screen_name")] public string GroupScreenName { get; set; }
[DataMember(Name = "is_closed")] public string GroupIsClosed { get; set; }
[DataMember(Name = "is_admin")] public string GroupIsAdmin { get; set; }
[DataMember(Name = "photo")] public string GroupPhoto { get; set; }
[DataMember(Name = "photo_medium")] public string GroupPhotoMedium { get; set; }
[DataMember(Name = "photo_big")] public string GroupPhotoBig { get; set; }
}
[DataContract] public partial class ProfilesList { [DataMember(Name = "uid")] public string ProfilesUid { get; set; }
[DataMember(Name = "first_name")] public string ProfilesFirstName { get; set; }
[DataMember(Name = "last_name")] public string ProfilesLastName { get; set; }
[DataMember(Name = "photo_rec")] public string ProfilesPhotoRec { get; set; }
[DataMember(Name = "photo")] public string ProfilesPhoto50x50 { get; set; }
[DataMember(Name = "photo_medium_rec")] public string ProfilesPhoto100x100 { get; set; }
[DataMember(Name = "screen_name")] public string ProfilesScreenName { get; set; } }
[DataContract] public partial class LikesList { [DataMember(Name = "count")] public string LikesCount { get; set; }
[DataMember(Name = "user_likes")] public string LikesUserLikes { get; set; } }
[DataContract] public partial class CommentsList { [DataMember(Name = "count")] public string CommentsCount { get; set; }
[DataMember(Name = "can_post")] public string CommentsCanPost { get; set; } }
[DataContract] public partial class ItemsNewsList { [DataMember(Name = "type")] public string ItemsNewsType { get; set; }
[DataMember(Name = "source_id")] public string ItemsNewsSourceId { get; set; }
[DataMember(Name = "date")] public string ItemsNewsDate { get; set; }
[DataMember(Name = "post_id")] public string ItemsNewsPostId { get; set; }
[DataMember(Name = "text")] public string ItemsNewsText { get; set; }
[DataMember(Name = "photo")] public string ItemsNewsPhoto { get; set; }
[DataMember(Name = "comments")] public CommentsList ItemsNewsComments { get; set; }
[DataMember(Name = "likes")] public LikesList ItemsNewsLikes { get; set; }
}
[DataContract] public partial class ItemNews { [DataMember(Name = "items")] public List<ItemsNewsList> ItemsResp { get; set; }
[DataMember(Name = "profiles")] public List<ProfilesList> ProfilesResp { get; set; }
[DataMember(Name = "groups")] public List<GroupsList> GroupsResp { get; set; }
}
[DataContract] public partial class NewsFeedResponse { [DataMember(Name = "response")] public ItemNews Response { get; set; }
} //Класс для десериализации public class JsonStringSerializer { public static T Deserialize<T>(string strData) where T : class { MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(strData)); DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); T tRet = (T)ser.ReadObject(ms);//response.ContentStream); ms.Close(); return (tRet); } }
private static NewsFeedResponse m_CurNewsFeed;
m_CurNewsFeed = JsonStringSerializer.Deserialize<NewsFeedResponse>(e.Result); //в e.Result находится тот JSON ответ от api.
lbNewsFeed.DataContext = m_CurNewsFeed.Response;
|
Данные десериализуются нормально, структура остается такая же как и в JSON ответе...
Далее код silverlight формы, точнее на форме листбокс, к которому и хочу сделать связывание данных:
Код |
<Grid x:Name="ContentGridNews" Grid.Row="1"> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <ListBox x:Name="lbNewsFeed" ItemsSource="{Binding Path=ItemsResp}"> <ListBox.ItemTemplate> <DataTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="80"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Image Source="{Binding Path=ItemsNewsPhoto}" Stretch="None" Height="100" Width="100"/> <TextBlock Grid.Column="1" Text="{Binding Path=ItemsNewsText}" VerticalAlignment="Center" Foreground="#6c85ad" FontSize="35"/> <TextBlock Grid.Column="2" Text="{Binding Path=ItemsNewsComments}" VerticalAlignment="Center" Foreground="#6c85ad" FontSize="35" Margin="5,0,0,0"/> </Grid> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
</Grid>
|
Для простоты в ListBox добавлено одно поле Image и два TextBlock. И проблема в том, что в ItemSource у ListBox можно указать какой-то один массив, т.е. либо Items, Profiles или Groups. В коде выше, указан только ItemsResp, и поэтому поля ItemsNewsPhoto, ItemsNewsText, ItemsNewsComments доступны для связывания с Image и двумя TextBlock соответственно. Но это получается, что будут выводится не все данные...А хотелось бы, чтобы было похоже на то как это выглядит на сайте Вконтакте, т.е. разные категории. Может в binding можно указывать несколько источников? или может кто-нибудь даст совет как решить мою проблему...и укажет на мои ошибки, спасибо за понимание.