所以我有一个运行查询并返回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,我希望将Column Headers绑定到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列表然后绑定到那些。
我可以使用一些帮助。
谢谢!
答案 0 :(得分:1)
我使用了上面的查询集类,并添加了一个在QuerySet类中构建DataTable的方法:
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集合,并根据QuerySet将每个Grid的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,而不是在后面的代码中进行转换。所以,虽然答案并不完美,但它现在仍然有用。