A
Adam Clauss
OK, I've really been struggling with the best way to go about this.
I have a read-only DataGridView bound via a BindingSource to a particular
table in a strongly typed DataSet/DataTable. I can sort, and everything
works fine.
But, rather than having a column header and then ALL the rows, I want to
have the various rows grouped into categories. Categories can have a
different number of rows, including NO rows (although the category header
should still show).
For example:
-------------------------------|
| Col1 | Col2 | Col3 |
| Category1 Title Here |
| r1c1 | r1c2 | r1c3 |
| r2c1 | r2c2 | r3c3 |
| r3c1 | r3c2 | r3c3 |
| Category2 Title Here |
| r4c1 | r4c2 | r4c3 |
| r5c1 | r5c2 | r5c3 |
|------------------------------|
Hopefull that text comes out close to correct.
So ALL my rows are still coming from one datatable, but (despite the fact
that I have the rows sequentially numbered) the rows for a given category
may very likely be spread out throughout the datatable.
The entire DataGridView should still scroll as one large list (individual
categories do not scroll independently).
I've tried a couple different approaches to this:
1) This is something of a migration from an existing web-based design. So,
I thought to best give me that functionality, I could use a FlowLayoutPanel
with a separate DataGridView for each category. The first category would
have it's column headers off, the others would be turned off. Upon the
first grid sorting, I would programmatically force the sort upon the other
DataGridViews.
This gave me several problems... first the FlowLayoutPanel was a PITA to
use. To prevent individual scrolling, I had to get the individual
DataGridViews to constantly resize themselves as their container
resized/rows were added (text of a cell might wrap). This... sorta worked,
but the second datagrid appeared where it was supposed to. Sometimes NEXT
to the previous datagridview, sometimes below it.
Other problem with this approach is keeping the columns aligned. I wanted
the entire object to more or less fill (horizontally) it's container. For
whatever reason (I think an issue with the FlowLayoutPanel), the second
DataGridView would never size itself as wide as the first.
2) Other option I tried was going back to one 'large' DataGridView. This
would give me the columns aligned like I wanted as well as scroll the entire
thing together. My thought was, derive my own custom "binding source" which
would actually itself a separate BindingSource object for each of the
categories (each would have an appropriate filter set on it). It would then
be my derived source's job to "concatentate" the lists as necessary to
provide to the DataGridView as well as pass on Sorting information to the
individual BindingSources. These concatenated lists would contain "special"
items in place for the category headers. An event handler for RowDataBound
could then detect these special items and change row appearance
appropriately.
This didn't work out either. Deriving directly from BindingSource, I
couldn't seem to actually intercept sending of the list of items to the
datagridview. I overrode a couple things (the implemented GetEnumerator(),
indexer [], etc). GetEnumerator() was never called. The indexer did get
called, but always with an index of 0 (which, comparing to the return value
of base was jsut returning the entire DataSet... or DataTable, I forget
which - in either case, the indexer was not being used to retrieve each
row).
Any thoughts about a better way to go about this? Was I heading down the
right path with either of these? Am I just completely in left field?
Thanks
I have a read-only DataGridView bound via a BindingSource to a particular
table in a strongly typed DataSet/DataTable. I can sort, and everything
works fine.
But, rather than having a column header and then ALL the rows, I want to
have the various rows grouped into categories. Categories can have a
different number of rows, including NO rows (although the category header
should still show).
For example:
-------------------------------|
| Col1 | Col2 | Col3 |
| Category1 Title Here |
| r1c1 | r1c2 | r1c3 |
| r2c1 | r2c2 | r3c3 |
| r3c1 | r3c2 | r3c3 |
| Category2 Title Here |
| r4c1 | r4c2 | r4c3 |
| r5c1 | r5c2 | r5c3 |
|------------------------------|
Hopefull that text comes out close to correct.
So ALL my rows are still coming from one datatable, but (despite the fact
that I have the rows sequentially numbered) the rows for a given category
may very likely be spread out throughout the datatable.
The entire DataGridView should still scroll as one large list (individual
categories do not scroll independently).
I've tried a couple different approaches to this:
1) This is something of a migration from an existing web-based design. So,
I thought to best give me that functionality, I could use a FlowLayoutPanel
with a separate DataGridView for each category. The first category would
have it's column headers off, the others would be turned off. Upon the
first grid sorting, I would programmatically force the sort upon the other
DataGridViews.
This gave me several problems... first the FlowLayoutPanel was a PITA to
use. To prevent individual scrolling, I had to get the individual
DataGridViews to constantly resize themselves as their container
resized/rows were added (text of a cell might wrap). This... sorta worked,
but the second datagrid appeared where it was supposed to. Sometimes NEXT
to the previous datagridview, sometimes below it.
Other problem with this approach is keeping the columns aligned. I wanted
the entire object to more or less fill (horizontally) it's container. For
whatever reason (I think an issue with the FlowLayoutPanel), the second
DataGridView would never size itself as wide as the first.
2) Other option I tried was going back to one 'large' DataGridView. This
would give me the columns aligned like I wanted as well as scroll the entire
thing together. My thought was, derive my own custom "binding source" which
would actually itself a separate BindingSource object for each of the
categories (each would have an appropriate filter set on it). It would then
be my derived source's job to "concatentate" the lists as necessary to
provide to the DataGridView as well as pass on Sorting information to the
individual BindingSources. These concatenated lists would contain "special"
items in place for the category headers. An event handler for RowDataBound
could then detect these special items and change row appearance
appropriately.
This didn't work out either. Deriving directly from BindingSource, I
couldn't seem to actually intercept sending of the list of items to the
datagridview. I overrode a couple things (the implemented GetEnumerator(),
indexer [], etc). GetEnumerator() was never called. The indexer did get
called, but always with an index of 0 (which, comparing to the return value
of base was jsut returning the entire DataSet... or DataTable, I forget
which - in either case, the indexer was not being used to retrieve each
row).
Any thoughts about a better way to go about this? Was I heading down the
right path with either of these? Am I just completely in left field?
Thanks