I am using the UltraWinGrid as a real-time log viewer. I want the grid to automatically display each new row as it is added to the bottom. Preferably, I would like this to be a design-time setting on the grid. If that's not available, I don't mind hooking the RowInserted event and doing some processing. Just not sure what processing to do.
I don't see an overload of the AddNew which accepts data... it only appears to create an empty row which the user can fill out. I guess I'm still not making myself quite clear.
I need to programatically add rows to a grid. The grid itself is entirely read-only from a user perspective. There is no ability to add, modify or delete rows from the UI (though it does support grouping, sorting, and filtering).
UltraGrid.Rows.Band.AddNew() does not take any data. And I cannot find a Add method (or anything like it) on the UltraGrid, the Rows collection or on the Band for the RowsCollection.
a) The AddNew method on the grid is on the Band.
b) If you add a row to the grid, it will automatically be scrolled into view, so you don't really need to worry about it.
An UltraDataSource doesn't have a current row, this is a concept of the CurrencyManager. So you could get the CurrencyManager from the grid's BindingContext and use that.
If you want to get the grid row from an UltraDataSource row, then you would have to loop through the grid rows and examine the ListObject property of each row to find the one that matches up to the UltraDataRow - probably not the most efficient way to go.
Hi Simon,
I had a very similar (possibly the same) problem yesterday. The way I got around it was to extend the UltraGrid class, and have the logging framework raise an event whenever the log was appended. Then the (extended) grid can have an event handler that does the appending (or just deals with the notification - your choice...) and after appending it can scroll to the end. I set it up so that the scrollbar was "sticky" - meaning it only scrolled to the end if it was already at the end before the latest addition. That way you can still browse around earlier entries, and go back to auto-scrolling by simply returning to the latest row.
Code below - it might not be a perfect setup, but it seems to be working for me so far.
Cheers,
- Sam.
public class LogViewerDataGrid : UltraGrid { . . . /// /// Handle a LogAppended event /// public void LogAppendedEventHandler(object sender, EventArgs e) { bool scrollToEnd = false; . .// setup . // if it's an empty grid, or we can already see the last row, set scrollToEnd = true if (DisplayLayout.Rows.Count > 0) { // if the last row in the grid is in the viewing area, set scrollToEnd = true UIElement rowUIElement = DisplayLayout.Rows[DisplayLayout.Rows.Count - 1].GetUIElement(); if (rowUIElement != null && rowUIElement.Rect != null) { scrollToEnd = true; } } else { scrollToEnd = true; } . .// add new row(s) to grid . // if the grid should be scrolled to the last row, do so now if (scrollToEnd) { DisplayLayout.RowScrollRegions[0].ScrollRowIntoView(DisplayLayout.Rows[DisplayLayout.Rows.Count - 1]); } } . . . }
As I dig into this a bit more, I guess I'm missing some key piece of information.
(a) First I thought I would ditch the data source and just add directly to the grid. Unfortunately, I can't figure out how to add rows directly to a grid. There is not a "Add" method on UltraDataGrid or UltraDataGrid.Rows (I'm probably looking in the wrong place).
(b) I looked at ActiveRow and ActiveRowScrollRegion... they seem fairly straightforward. Except they operate on UltraGridRows... not UltraDataRows (which is what I get back from the UltraDataSource). Given a datasource row, how do I correlate it to a grid row?
I apologize for being ignorant here... I suspect that I'm missing some key architectural information about how infragistics UI does the separation of concerns between data objects and presentation objects. Unfortunately the help is not revealing in this case... it's probably buried somewhere but I'm having a great deal of difficultly mining information from either the help or from intellisense.
Thanks for the reply! I apologize for not giving enough info.
I am indeed doing all data writes via a ultradatasource and I let the data binding to the grid take care of the rest. How do you set the Current row via a data source? Or do I need to take the UltraDataRow object passed from UltraDataSource.Add() and pass it directly to UltraDataGrid.Current?