【问题标题】:DataBinding deserialized json arrayDataBinding 反序列化 json 数组
【发布时间】:2012-01-24 06:00:00
【问题描述】:

我对 C#、silverlight 和整个数据绑定范例比较陌生。我一直在开发一个小测试应用程序,它使用 Json.Net 通过他们的API 从 reddit 中提取数据。无论如何,我可以很好地将数据放入我的应用程序,但现在我无法将数据推送到 UI 中。我尝试了几种不同的配置均无济于事。无论如何,代码在这里:

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

这是我的代码的主要部分。其余的类都在这里,它们是用于 reddit 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>

标题包含在名为 topic 的 RootObject 实例中。所以获取标题的方法是

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

但是,我几乎不知道如何将其绑定到这些文本框或列表框。我知道必须设置数据上下文,并且可以通过代码而不是 xaml 来绑定这些项目,但我不知道找出任何优雅的方式来做到这一点。有什么帮助吗?非常感谢。

【问题讨论】:

    标签: c# windows-phone-7 data-binding reddit


    【解决方案1】:

    从外观上看,你快到了。您的问题是您试图将整个页面的 DataContext 设置为一条记录中的单个标题(this.DataContext = topic.data.children[0].data.title;) - 这可能不是您的意思......

    要将数据放入您的 ListBox,您有 2 个选项 - 您可以像这样显式设置 ListBox 的 ItemsSource

    myListBox.ItemsSource = topic.data.children;
    

    然后更新 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>
    

    但是,如果您希望在页面的其他位置使用数据,您可能需要为整个页面设置 DataContext。

    DataContext = topic;  
    

    并将 ListBox 上的 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>
    

    希望这会有所帮助。

    【讨论】:

    • 这正是我想要的。我试图定义数据上下文的方式并不打算在这里发布,它更像是在黑暗中刺伤,我知道可能行不通并且忘记删除。无论如何,我已经研究过数据绑定以寻找这些类型的示例,但一无所获。它完美地工作。谢谢。
    【解决方案2】:

    如果要处理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>
    

    【讨论】:

      猜你喜欢
      • 2015-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多