2016-12-07 4 views
0

Итак, у меня есть вызов api, который запускает запрос и возвращает ответ JSON. Из-за структуры ответа JSON я создал класс, который я могу использовать Json.Net для десериализации возврата прямо в. Вот пример класс:Данные привязки DataGrid к объекту с вложенными классами

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, я хочу, чтобы заголовки столбцов, связанные с собственностью Имя и данные, заполненные данными 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, я попытался установить DataGrid в ListBox в XAML, но я, возможно, не реализовал это правильно и, наконец, пришел к решению попытаться создать список DataGrids, а затем привязаться к ним.

Я мог бы воспользоваться помощью.

Спасибо!

ответ

1

SO после некоторого возиться с этим. Вот ответ, который я придумал.

Я взял множество запросов класса выше и добавлен метод для создания DataTable внутри QuerySet класса:

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 оттуда. В моем коде позади моего всплывающего окна, я создал Observable Коллекция DataGrids и установить DataContext каждой сетки в DataView на основе QuerySet:

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> 

Очевидно, что это не самое изящное решение. Даже просто глядя на него, я мог бы легко создать DataView в классе QuerySet, а не делать это преобразование в коде. Итак, хотя ответ не идеальный, он работает пока.