SPARQL results in WPF (binding DataGrid) -
i use dotnetrdf , display results query in wpf. function in viewmodel. have datatable use next in view.
//results sparqlresultset results; datatable table; //define remote endpoint //use dbpedia sparql endpoint default graph set dbpedia sparqlremoteendpoint endpoint = new sparqlremoteendpoint(new uri("http://dbpedia.org/sparql"), "http://dbpedia.org"); //make select query against endpoint results = endpoint.querywithresultset("prefix dbo: <http://dbpedia.org/ontology/> prefix : <http://dbpedia.org/resource/> select ?film ?producername { ?film dbo:director :andrzej_wajda . ?film dbo:producer ?producername . }"); foreach (sparqlresult result in results) { console.writeline(result.tostring()); } table = new datatable(); datarow row; switch (results.resultstype) { case sparqlresultstype.variablebindings: foreach (string var in results.variables) { table.columns.add(new datacolumn(var, typeof(inode))); } foreach (sparqlresult r in results) { row = table.newrow(); foreach (string var in results.variables) { if (r.hasvalue(var)) { row[var] = r[var]; } else { row[var] = null; } } table.rows.add(row); } break; case sparqlresultstype.boolean: table.columns.add(new datacolumn("ask", typeof(bool))); row = table.newrow(); row["ask"] = results.result; table.rows.add(row); break; case sparqlresultstype.unknown: default: throw new invalidcastexception("unable cast sparqlresultset datatable resultset has yet filled data , has no sparqlresultstype determines how cast datatable"); }
in wpf use code:
<datagrid itemssource="{binding table}" autogeneratecolumns="true"/>
binding work , dynamic created columns , datagrid, header. don't value of rows. in example there rows, without values.
where problem ? lot :)
this question not dotnetrdf other starting data sparql query how datagrid
behaves when itemssource
datatable
, autogeneratecolumns
used.
the basic problem datagrid
not know how display arbitrary data types , generates datagridtextcolumn auto-generated columns. unfortunately supports string
values or types explicit ivalueconverter
applied afaik, doesn't call tostring()
because conversions expected 2 way hence why see empty columns (thanks this question explaining this).
so getting values appropriately displayed requires create datatemplate
our columns use. want use autogeneratecolumns
need add handler autogeneratingcolumns
event so:
<datagrid itemssource="{binding table}" autogeneratecolumns="true" autogeneratingcolumn="autogeneratingcolumn" />
next need add implementation of event handler apply appropriate column type each auto-generated column so:
private void autogeneratingcolumn(object sender, system.windows.controls.datagridautogeneratingcolumneventargs e) { if (e.propertytype != typeof (inode)) return; datatabledatagridtemplatecolumn column = new datatabledatagridtemplatecolumn(); column.columnname = e.propertyname; column.clipboardcontentbinding = e.column.clipboardcontentbinding; column.header = e.column.header; column.sortmemberpath = e.column.sortmemberpath; column.width = e.column.width; column.celltemplate = (datatemplate) resources["nodetemplate"]; e.column = column; }
note use of special datatabledatagridtemplatecolumn
type here, class answer binding wpf datagrid datatable using templatecolumns renamed more descriptive.
the reason can't use datagridtemplatecolumn directly when binding datatable
template each column passed entire row rather specific column value need extend class in order bind specific column value our template formats actual inode
value column in row , not whole row.
finally need define template we've referred in our xaml our columns appropriately formatted:
<window.resources> <sparqlresultsdatagridwpf:methodtovalueconverter x:key="methodtovalueconverter" /> <datatemplate x:key="nodetemplate" datatype="rdf:inode"> <textblock text="{binding converter={staticresource methodtovalueconverter}, converterparameter='tostring'}"/> </datatemplate> </window.resources>
note i've defined value converter here, methodtovalueconverter
taken answer of bind method in wpf? , allows take result of method call on arbitrary type , use our display value. here configuration of our template calls tostring()
on underlying inode
instances.
with these things implemented run example query , following in datagrid
:
you can find code used @ https://bitbucket.org/rvesse/so-23711774
you can use basic approach construct more robust rendering of inode
many visual bells , whistles see fit.
side notes
a couple of notes related answer, firstly have been easier produce if had posted minimal complete example of code rather partial xaml , code fragments.
secondly dotnetrdf sparqlresultset
class has explicit cast datatable
defined shouldn't need manually translate datatable
unless want control structure of datatable
e.g.
datatable table = (datatable) results;
Comments
Post a Comment