wpf - Dynamically generating 2D grid with row and column headers -
i'm starting out ireactivelist<icoordvm>
where:
interface icoordviewmodel { object x {get;} object y {get;} viewmodel viewmodel {get;} }
i'd create grid list view each viewmodel located @ appropriate x/y coordinate. additionally, rows , columns must labeled according to, say, tostring()
values of x , y. finally, i'd avoid redrawing entire grid new items added list.
i'm deliberating whether use grid, datagrid, or else. using datatable/datagrid described in second solution here seems me row , header columns, seems i'll need inject new datatable , redraw screen every time item added. using gridhelpers described in this solution might give me way avoid redraw, there's no description how include row , column headers.
anyone have creative ideas how tackle this?
here's solution came with. this link helped tremendously; pirated xaml directly:
<datatemplate x:key="datatemplatelevel2"> <contentpresenter content="{binding}"/> </datatemplate> <datatemplate x:key="datatemplatelevel1"> <itemscontrol itemssource="{binding}" itemtemplate="{dynamicresource datatemplatelevel2}"> <itemscontrol.itemspanel> <itemspaneltemplate> <stackpanel orientation="horizontal"/> </itemspaneltemplate> </itemscontrol.itemspanel> </itemscontrol> </datatemplate> <datatemplate datatype="{x:type viewmodels:displaygridviewmodel}"> <scrollviewer verticalscrollbarvisibility="auto" horizontalscrollbarvisibility="auto"> <itemscontrol itemssource="{binding lists}" itemtemplate="{dynamicresource datatemplatelevel1}"/> </scrollviewer> </datatemplate>
below stripped-down version of viewmodel. basic trick initialize method called when grid dimensions known; method populates grid following:
- cells: items of type icoordviewmodel
- row headers: items of type rowheaderviewmodel
- column headers: items of type columnheaderviewmodel
- corner: item of type cornerheaderviewmodel.
next, new viewmodels arrive, add method called find x/y location viewmodel should placed, , injected placeholder; , happens displayed in grid in appropriate location. (all viewmodels template in xaml).
public class displaygridviewmodel { // fields , constructor. public void initialize() { var rows = getrows().tolist(); var columns = getcolumns().tolist(); _lists.clear(); var cornerheader = new cornerheaderdisplayviewmodel(_displayeditor /* + other content */); var columnheaders = columns.select(c => new columnheaderviewmodel(c, _displayeditor)); _lists.add(new reactivelist<object>(enumerable.repeat((object)cornerheader, 1).union(columnheaders))); var index = 1; foreach (var row in rows) { _lists.add(new reactivelist<object>()); _lists[index].add(new rowheaderviewmodel(row, _displayeditor /* + other content */)); foreach (var column in columns) { _lists[index].add(new cellviewmodel(_displayeditor /* + other content */)); } index++; } } private ienumerable<object> getrows() { // custom implementation } private ienumerable<object> getcolumns() { // custom implementation } public void add(icoordchart coordchart) { var match = _lists.selectmany(l => l).oftype<coordviewmodel>().single(cc => ismatch(cc, coordchart)); match.viewmodel = coordchart.viewmodel; } private static bool ismatch(icoordchart cc, icoordchart chart) { // custom implementation } private readonly ireactivelist<ireactivelist<object>> _lists = new reactivelist<ireactivelist<object>>(); public ireactivelist<ireactivelist<object>> lists { { return _lists; } } }
finally there displayeditorviewmodel provides central location cell width , height. allows user adjust display dimensions elsewhere on ui , cells automatically resized.
apologies that's unclear. code here provide decent balance between providing high-level clues others tackling issue while avoiding unnecessary detail.
Comments
Post a Comment