2011-12-20 64 views
0

我對C#,silverlight和整個數據綁定範例都比較陌生。我一直在研究一個小測試應用程序,它使用Json.Net通過API從reddit獲取數據。無論如何,我將數據輸入到我的應用程序中就好了,但現在我無法將數據推送到用戶界面。我嘗試了幾種不同的配置無濟於事。無論如何,代碼是在這裏:DataBinding反序列化的json數組

public partial class MainPage : PhoneApplicationPage 
{ 
    string json = ""; 
    RootObject topic { get; set; } 
    public MainPage() 
    { 
     InitializeComponent(); 
    } 
    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     textBlock1.Text = "Retrieving..."; 
     string url = @"http://www.reddit.com/r/all.json"; 
     HttpWebRequest hWebRequest = (HttpWebRequest)HttpWebRequest.Create(url); 
     hWebRequest.Method = "GET"; 
     hWebRequest.BeginGetResponse(Response_Completed, hWebRequest); 
    } 
    public void Response_Completed(IAsyncResult result) 
    { 
     HttpWebRequest request = (HttpWebRequest)result.AsyncState; 
     HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result); 
     using (StreamReader streamReader = new StreamReader(response.GetResponseStream())) 
     { 
      json = streamReader.ReadToEnd(); 
      topic = JsonConvert.DeserializeObject<RootObject>(json); 
     } 
     Deployment.Current.Dispatcher.BeginInvoke(() => 
     { 
      this.DataContext = topic.data.children[0].data.title; 
      textBlock1.Text = "Done."; 
     }); 
    } 

這是我的代碼的主要部分。其餘的類都在這裏,它們用於反編譯API提供的JSON的反序列化。

public class MediaEmbed 
    { 
     public string content { get; set; } 
     public int? width { get; set; } 
     public bool? scrolling { get; set; } 
     public int? height { get; set; } 
    } 
    public class Oembed 
    { 
     public string provider_url { get; set; } 
     public string description { get; set; } 
     public string title { get; set; } 
     public string url { get; set; } 
     public string author_name { get; set; } 
     public int height { get; set; } 
     public int width { get; set; } 
     public string html { get; set; } 
     public int thumbnail_width { get; set; } 
     public string version { get; set; } 
     public string provider_name { get; set; } 
     public string thumbnail_url { get; set; } 
     public string type { get; set; } 
     public int thumbnail_height { get; set; } 
     public string author_url { get; set; } 
    } 
    public class Media 
    { 
     public string type { get; set; } 
     public Oembed oembed { get; set; } 
    } 
    public class Data2 
    { 
     public string domain { get; set; } 
     public MediaEmbed media_embed { get; set; } 
     public object levenshtein { get; set; } 
     public string subreddit { get; set; } 
     public string selftext_html { get; set; } 
     public string selftext { get; set; } 
     public object likes { get; set; } 
     public bool saved { get; set; } 
     public string id { get; set; } 
     public bool clicked { get; set; } 
     public string title { get; set; } 
     public Media media { get; set; } 
     public int score { get; set; } 
     public bool over_18 { get; set; } 
     public bool hidden { get; set; } 
     public string thumbnail { get; set; } 
     public string subreddit_id { get; set; } 
     public string author_flair_css_class { get; set; } 
     public int downs { get; set; } 
     public bool is_self { get; set; } 
     public string permalink { get; set; } 
     public string name { get; set; } 
     public double created { get; set; } 
     public string url { get; set; } 
     public string author_flair_text { get; set; } 
     public string author { get; set; } 
     public double created_utc { get; set; } 
     public int num_comments { get; set; } 
     public int ups { get; set; } 
    } 
    public class Child 
    { 
     public string kind { get; set; } 
     public Data2 data { get; set; } 
    } 
    public class Data 
    { 
     public string modhash { get; set; } 
     public Child[] children { get; set; } 
     public string after { get; set; } 
     public object before { get; set; } 
    } 
    public class RootObject 
    { 
     public string kind { get; set; } 
     public Data data { get; set; } 
    }  
} 

假設的XAML UI的東西看起來像這樣

  <ListBox> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <StackPanel> 
         <TextBlock x:Name="TitleInfo" /> 
         <TextBlock x:Name="AuthorInfo" /> 
        </StackPanel> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 

的標題包含RootObject實例的內部調用話題。因此,要搶冠軍的方式是

topic.data.children[0].data.title; 

不過,我幾乎沒有任何想法我怎麼能結合,對這些文本框或listbox..I知道一個DataContext必須設置這些項目可以綁定通過代碼,而不是XAML,但我無法找出任何優雅的方式來做到這一點。任何幫助?萬分感謝。

回答

1

從外表看,你幾乎就在那裏。你的問題是,你試圖將整個頁面的DataContext設置爲一個記錄中的單個標題(this.DataContext = topic.data.children[0].data.title;) - 這可能不是你的意思...

要將數據放入ListBox,你有2個選擇 - 你可以明確地像這樣

myListBox.ItemsSource = topic.data.children; 

設置的ItemsSource列表框,然後更新XAML顯示來自對象圖中該點的數據...

<ListBox Name="MyListBox"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel> 
       <TextBlock x:Name="TitleInfo" Text="{Binding data.title}" /> 
       <TextBlock x:Name="AuthorInfo" Text="{Binding data.author}" /> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

然而,如果你正在尋找在t中的其他地方使用數據他的頁面,你可能會想要爲整個頁面設置DataContext。

DataContext = topic; 

和你的列表框XAML設置的東西稍微不同......

<ListBox Name="MyListBox" ItemsSource="{Binding data.children}" > 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel> 
       <TextBlock x:Name="TitleInfo" Text="{Binding data.title}" /> 
       <TextBlock x:Name="AuthorInfo" Text="{Binding data.author}" /> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

希望這有助於。

+0

這是非常正是我一直在尋找。我試圖定義數據上下文的方式並不意味着在這裏發佈,它更像是在黑暗中刺中,我知道可能不會工作,並忘記刪除。無論如何,我研究過尋找這些類型的例子的數據綁定,但什麼都沒發現。它完美的作品。謝謝。 – Wilcoholic 2011-12-20 09:23:51

0

如果要處理DataBinidng,最好實施MVVM模式。

在此期間,這裏就是你們的榜樣的修復:

public partial class MainPage : PhoneApplicationPage, INotifyPropertyChanged 
{ 
    string json = ""; 
    private RootObject topic; 

    public event PropertyChangedEventHandler PropertyChanged; 

    public RootObject Topic 
    { 
     get 
     { 
      return this.topic; 
     } 
     set 
     { 
      this.topic = value; 
      var handler = this.PropertyChanged; 
      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs("Topic")); 
      } 
     } 
    } 

    public MainPage() 
    { 
     InitializeComponent(); 
     this.DataContext = this; 
    } 
    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     ... 
    } 
    public void Response_Completed(IAsyncResult result) 
    { 
     HttpWebRequest request = (HttpWebRequest)result.AsyncState; 
     HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result); 
     using (StreamReader streamReader = new StreamReader(response.GetResponseStream())) 
     { 
      json = streamReader.ReadToEnd(); 
      this.Topic = JsonConvert.DeserializeObject<RootObject>(json); 
     } 
    } 
} 

和更新的XAML:

<ListBox Name="MyListBox" ItemsSource="{Binding Topic.data.children}" > 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel> 
       <TextBlock x:Name="TitleInfo" Text="{Binding data.title}" /> 
       <TextBlock x:Name="AuthorInfo" Text="{Binding data.author}" /> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 
+0

我會考慮MVVM,感謝您的鏈接。 – Wilcoholic 2011-12-20 09:25:00