C# 数据绑定反序列化json数组

C# 数据绑定反序列化json数组,c#,windows-phone-7,data-binding,reddit,C#,Windows Phone 7,Data Binding,Reddit,我对C#、silverlight和整个数据绑定范式都比较陌生。我一直在开发一个小测试应用程序,它使用Json.Net从reddit中提取数据。无论如何,我把数据输入到我的应用程序中很好,但是现在我在把数据推到UI中时遇到了麻烦。我尝试了几种不同的配置,但都没有效果。无论如何,代码在这里: public partial class MainPage : PhoneApplicationPage { string json = ""; RootObject topic { get;

我对C#、silverlight和整个数据绑定范式都比较陌生。我一直在开发一个小测试应用程序,它使用Json.Net从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.";
        });
    }
让我们假设XAMLUI的东西看起来像这样

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

但是,我几乎不知道如何将其绑定到这些文本框或列表框。我知道必须设置datacontext,并且可以通过代码(而不是xaml)绑定这些项,但我无法想出任何优雅的方法来实现这一点。有什么帮助吗?非常感谢。

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

要将数据放入ListBox,您有两个选项—您可以像这样显式地设置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>
并将列表框上的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>


希望这能有所帮助。

如果您想处理数据绑定,最好实现模式

同时,以下是对您的示例的修复:

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);
        }
    }
}
公共部分类主页面:PhoneApplicationPage,INotifyPropertyChanged
{
字符串json=“”;
私有对象主题;
公共事件属性更改事件处理程序属性更改;
公共根对象主题
{ 
得到
{
返回此.topic;
}
设置
{
this.topic=值;
var handler=this.PropertyChanged;
if(处理程序!=null)
{
处理程序(此,新属性ChangedEventArgs(“主题”);
}
}
}
公共主页()
{
初始化组件();
this.DataContext=this;
}
私有无效按钮1\u单击(对象发送者,路由目标)
{
...
}
公共无效响应_已完成(IAsyncResult结果)
{
HttpWebRequest请求=(HttpWebRequest)result.AsyncState;
HttpWebResponse=(HttpWebResponse)request.EndGetResponse(result);
使用(StreamReader StreamReader=newstreamreader(response.GetResponseStream()))
{
json=streamReader.ReadToEnd();
this.Topic=JsonConvert.DeserializeObject(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>

这正是我想要的。我试图定义数据上下文的方式并不是要发布在这里,它更像是一种暗箭伤人的做法,我知道这可能行不通,所以忘了删除。无论如何,我已经研究了数据绑定,寻找这类示例,但什么也没有找到。它工作得很好。谢谢
<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>
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);
        }
    }
}
<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>