❔ WPF Dynamic DataGrid
I need to be able to build a DataGrid to support a dynamic (I.E. determined at runtime) set of columns. I'm hoping to be able to use a
DataGrid
instead of building a custom control of some kind that's just build on top of a Grid
, because there's a lot of nice stuff that DataGrid
supports, like sorting.
Reason being, I'm trying to build a UI where the user can import CSV files. I want the UI to display the CSV file (at least in part) in its raw form, I.E. just a pure table of nothing but strings. This gives the user a chance to look at it, and then assign which columns have which functional meaning, for further parsing. It will also be able to give feedback on validation, E.G. highlight cells as invalid in the column they've designated as "Date", if those cells contain invalid date values.
Setting up the columns was fairly straightforward, I wrote a Behavior<T>
that gives me a HeadersSource
property I can bind to, to define how many columns there are, and what their names are (parsed out of the CSV document).
I'm not sure how I can proceed from here, though. Ultimately, what I suppose I need is a way to pass down the column index to each cell, for use in binding. I think in theory what I could do with DataGridTemplateColumn is....
That is, DataGrid.ItemsSource
is bound to an array/list of the cell ViewModels, and each column needs to bind to the item at the appropriate index of the array. From there, the ContentPresenter
should be able to retrieve the appropriate View for the ViewModel type from resources, and everything should be good. But I don't know how to do the programmatic equivalent of that CellTemplate
20 Replies
Why, instead of having a
dynamic
don't you use a DataTable
or create a data structure to support that?
If you have a data structure you can directly bind the data - so you will not need to make loops and populate the table manuallythere is no use of
dynamic
anywhere in that code
building a data structure to model this is precisely what I'm doing
that's what DraftsCsvImportWorkspaceModel
isAh understood
I mean a data structure where you can bind it directly to a DataGrid
like a list
(not sure if all IEnumerable implementations)
because DataGrid doesn't support that
it supports binding a set of rows
BindingList?
with you explicitly defining columns
Are u sure? Im not sure abt that, like, I thought you could put a common list as data source
or it supports the AutoGenerateColumns=True option, which generates columns based on object properties, not based on the columns being an arbitrary array
isn't BindingList a WinForms thing?
So, do you also have dynamic columns?
I dont remember
I used to do desktop a long ago
I have dynamic columns in the sense that I don't know how many there are or what their names are until runtime
Understood
well, my thoughts are pretty cursed about that
(reflection)
I mean
have you tried to use DataTable.DefaultView to populate the grid?
there is no reflection going on here
no no
forget about the reflection
no, I am not using a DataTable
is not related to what i said now
this is not coming from a database
I know
but you dont need to have a database to use datatable
you can make your own DataTable instance with your data
then, put the instance as your DataGrid ItemsSource
I mean, I think it is a dirty solution but that all that I can think @ReactiveVeina
yeah, I don't see how that's going to work
there doesn't appear to be any way for me to stick a ViewModel into a
DataColumn
I can only create a DataColumn
with a string columnName
value, and a couple other metadata parameters
in theory, I could just setup the HeaderTemplate
to be the same for every column, and have it bind to stuff on the WorkspaceModel
but then I'd have no way to identify which column was calling into WorkspaceModel
we're right back to the original question, really
so, yeah, this works
(bullshit binding hack aside)
all I need is a way to programmatically generate that DataTemplate
cause my programmatic generation of the <DataGridTemplateColumn>
s, with Header
values is already working
bingoboyah
good
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.