2016-12-07 123 views
0

因此,我有一个运行查询并返回JSON响应的api调用。由于JSON响应的结构,我创建了一个可以使用Json.Net反序列化返回的类。下面是示例类:将数据网格绑定到具有嵌套类的对象

public class QuerySet 
{ 
    public List<Column> Columns { get; set; } 
    public class Column 
    { 
     public List<string> Name { get; set; } 
    } 
    public List<RowSet> Rows { get; set; } 
    public class RowSet 
    { 
     public List<DataSet> Row { get; set; } 
     public class DataSet 
     { 
      public List<string> Data { get; set; } 
     } 
    } 
} 

现在,一个API调用可以包含多个查询集,所以对于每一个回报,我生成的查询集列表,我再想数据的DataGrid绑定到每组。这里是什么,我至今在我的窗口后面的代码示例:

public List<DataGrid> QueryResults; 

    public QueryResultsWindow(string _name, JObject _returns) 
    { 
     InitializeComponent(); 
     QueryNameText.Text = _name; 
     QueryResults = new List<DataGrid>(); 

     JArray sets = (JArray)_returns.SelectToken("$..Set"); 

     foreach(JObject set in sets) 
     { 
      DataGrid dg = new DataGrid(); 
      QuerySet s = new QuerySet(); 
      s = JsonConvert.DeserializeObject<QuerySet>(set.ToString()); 

      dg.ItemsSource = s.Rows; 

      QueryResults.Add(dg); 
     } 

     ResultsListBox.ItemsSource = QueryResults; 
    } 

在这里,你可能会看到的问题是,对于每一个特定的DataGrid,我想绑定到Name属性列标题,并从Data属性填充的数据。

这里是我目前在该窗口中的XAML设置:

<DockPanel> 
     <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" VerticalAlignment="Top"> 
      <TextBlock x:Name="QueryNameText" Margin="5"></TextBlock> 
      <Button Content="Export Results" Click="Button_Click" Margin="5"></Button> 
     </StackPanel> 
     <ListBox DockPanel.Dock="Top" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="3" Name="ResultsListBox"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <DataGrid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding UpdateSourceTrigger=PropertyChanged}" CanUserAddRows="False" IsReadOnly="True" SelectionUnit="Cell"> 
         <DataGrid.Columns> 
          <DataGridTextColumn Header="{Binding Name}"></DataGridTextColumn> 
         </DataGrid.Columns> 
        </DataGrid> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 
    </DockPanel> 

我知道,如果我想为每个可能的返回类型的自定义类,这将容易得多。但是,考虑到数百种潜在的回报类型,这似乎不太可行。我试过使用DataTables,我试着在XAML的ListBox中设置DataGrid,但是我可能没有正确实现它,最后来到试图创建DataGrids列表然后绑定到这些列表的解决方案。

我可以使用一些帮助。

谢谢!

回答

1

因此,这一切搞砸了。这是我提出的答案。

我把查询集类以上,并增加了一个方法来构建查询集类中的数据表:

public class QuerySet 
    { 
     public DataTable BindableTable { get; private set; } 
     public static List<string> ColumnName { get; private set; } 
     public static List<RowSet.DataSet> RowsSet { get; private set; } 

     public List<Column> Columns { get; set; } 
     public class Column 
     { 
      private List<string> _name; 

      public List<string> Name 
      { 
       get { return _name; } 
       set { _name = value; ColumnName = _name; } 
      } 


     } 
     public List<RowSet> Rows { get; set; } 

     public class RowSet 
     { 
      private List<DataSet> _row; 

      public List<DataSet> Row 
      { 
       get { return _row; } 
       set { _row = value; RowsSet = _row; } 
      } 

      public class DataSet 
      { 
       public List<string> Data { get; set; } 
      } 
     } 

     public void GetDataGridTable() 
     { 
      DataTable table = new DataTable(); 
      foreach(string name in ColumnName) 
      { 
       table.Columns.Add(name); 
      } 
      foreach(RowSet.DataSet set in RowsSet) 
      { 
       DataRow row = table.NewRow(); 
       int counter = 0; 
       foreach(string item in set.Data) 
       { 
        row[counter] = item; 
        counter++; 
       } 
       table.Rows.Add(row); 
      } 

      BindableTable = table; 
     } 
    } 

我增加了几个存取,使得到的嵌套位更容易,并建立一个DataTable从那里。在我的弹出窗口的后面我的代码,我创建DataGrid中的一个观察的集合,并设置每个网格的DataContext的基于该查询集一个DataView:

public ObservableCollection<DataGrid> QueryResults; 
    public event PropertyChangedEventHandler PropertyChanged; 

    public QueryResultsWindow(string _name, JObject _returns) 
    { 
     InitializeComponent(); 
     QueryNameText.Text = _name; 
     QueryResults = new ObservableCollection<DataGrid>(); 

     JArray sets = (JArray)_returns.SelectToken("$..Set"); 

     foreach(JObject set in sets) 
     { 
      DataGrid dg = new DataGrid(); 
      QuerySet s = new QuerySet(); 
      s = JsonConvert.DeserializeObject<QuerySet>(set.ToString()); 

      s.GetDataGridTable(); 
      DataView newView = new DataView(s.BindableTable); 
      dg.ItemsSource = newView; 
      dg.CanUserAddRows = false; 
      dg.CanUserDeleteRows = false; 
      QueryResults.Add(dg); 
     } 

     ResultsListBox.ItemsSource = QueryResults; 
    } 

然后我的弹出式窗口中的XAML是非常简单的:

<DockPanel> 
    <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" VerticalAlignment="Top"> 
     <TextBlock x:Name="QueryNameText" Margin="5"></TextBlock> 
     <Button Content="Export Results" Click="Button_Click" Margin="5"></Button> 
    </StackPanel> 
    <ListBox DockPanel.Dock="Top" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="3" Name="ResultsListBox" ItemsSource="{Binding QueryResults}"> 
    </ListBox> 
</DockPanel> 

显然这不是最优雅的解决方案。即使只是在这里查看它,我可以轻松地在QuerySet类中创建DataView,而不是在后面的代码中进行转换。所以,虽然答案并不完美,但它现在还在工作。