Hi,
I'm trying to figure out how to set the ActiveRow to the same scrolled position after data updates. Example if it's in the 5th position before rows aer added or deleted I want it displayed back in the 5th position (viewindex). The ScrollPosition of the row is not accessable.
Please look at the enclosed example and tell me where I've gone awry.
//random generated junk from mockaroo.com #region string sampleData = @"6,Thomas,Hunter,thunter5@ucoz.com,Male,124.126.178.0, 7,Aaron,Robertson,arobertson6@squarespace.com,Male,206.206.106.42, 8,Judith,Price,jprice7@edublogs.org,Female,215.33.252.254, 9,Howard,Ortiz,hortiz8@go.com,Male,122.12.248.126, 10,Douglas,Snyder,dsnyder9@amazonaws.com,Male,28.22.144.247".Trim(); #endregion
string[] values = sampleData.Split(',');
UltraGridRow prevRow = this.ultraGrid1.Rows.OfType<UltraGridRow>() .ToList() .Find(r => r.Cells[0].Text.Equals(_activeId.ToString(), StringComparison.CurrentCultureIgnoreCase));
for (int index = 0; index < values.Count(); index += 6) { var data = values.Skip(index).Take(6).Select(x => x.ToString().Trim()).ToArray(); _sampleData.Add(new SampleData() { ID = Convert.ToInt16(data[0]), FirstName = data[1].ToString(), LastName = data[2].ToString(), Email = data[3].ToString(), Gender = data[4].ToString(), IPAddress = data[5].ToString() }); }
_sampleData = _sampleData.OrderBy(o => o.ID).ToList();
ultraDataSource1.Rows.SetCount(_sampleData.Count); ultraDataSource1.ResetCachedValues();
UltraGridRow row = this.ultraGrid1.Rows.OfType<UltraGridRow>() .ToList().Find(r => r.Cells[0].Text.Equals(_activeId.ToString(), StringComparison.CurrentCultureIgnoreCase));
ultraGrid1.ActiveRow = row; var activeIndex = ultraGrid1.ActiveRow.Index;
ultraGrid1.ActiveRowScrollRegion.ScrollPosition = prevRow.VisibleIndex; ultraGrid1.Rows[activeIndex].Activate(); ultraGrid1.Rows[activeIndex].Selected = true; ultraGrid1.ActiveRowScrollRegion.ScrollRowIntoView(row);
Thanks,
Glenn
Hi Glenn,
Thanks for sending your source. I'm currently looking into how you can achieve this and I plan to build a sample for you.
I should have the sample ready by the end of the day on Thursday. Please let me know if you have any questions.
After taking a closer look at this, I feel that it's generally not a good idea to do, since it can cause a host of issues and would be difficult to maintain.
One issue is that the active row before a data update may not be the same instance of the UltraGridRow object after a data update. If new data is bound to the grid, it will be necessary to figure out which row you are looking for. You might be able to accomplish this by using a primary key value to identify the row, but it will not be 100% reliable. There is also, of course, no guarantee that the old active row even exists in the new data.
Another issue occurs if rows are added or deleted in such a way that makes it impossible for the active row to maintain its position (for example, if it was the fifth row down and there are no longer four rows before it). This special case, and others like it, would have to be handled manually in your code.
A final issue is that behavior can become inconsistent based on how the user is adding or deleting rows. A newly added row normally becomes the active row and users will have to click on a row to delete it, which would cause that row to become active. In this situation, the active row would become another row in the grid and users may not understand why the grid is being scrolled automatically after deleting a row.
May I ask why you need to maintain the scroll position of the active row after making changes to the datasource? If possible, I will try to recommend a different approach.
It's a business requirement. We are migrating a VB6 application to .Net. We decided to use Infragistics over Telerik because Infragistics offers a cleaner way of doing things like this. In the VB6 application the row stays the same after grid updates with the exception if that row was removed.
So it's one of those things that when the users transition over to the new application they have the same look and feel as the old one. Honestly, I tried to get them to do things int the 2010's vs the 90's but I lost the argument over how the 20,000+ users have been using the application.
So if this can't be done please let me know.
The key here is that you need to use the FirstRow property on the grid's ActiveScrollRegion:
this.ultraGrid1.ActiveRowScrollRegion.FirstRow
You can't actually store the row itself, since the data source will likely return new objects after the change than before, and therefore the grid will create all new instances of the UltraGridRow objects for the new rows. But you can use the index.
So to store the position, you do this:
int index = this.ultraGrid1.ActiveRowScrollRegion.FirstRow.Index
And to restore it, you do this:
this.ultraGrid1.ActiveRowScrollRegion.FirstRow = this.ultraGrid1.Rows[index]'
Thanks, I'll give that a shot.
Hi Mike,
You were closer than I was. The trick was to get the distance from the ActiveRow to the FirstRow and reapply the same distance. AFAIK, it works like a charm.
Code update is below if anyone else wants to look at it.
private void button2_Click(object sender, EventArgs e) {
button2.Enabled = false;
this.ultraGrid1.SuspendLayout();
int rowIndex = this.ultraGrid1.ActiveRowScrollRegion.FirstRow.Index;
rowIndex = this.ultraGrid1.ActiveRow.VisibleIndex - rowIndex; //distance between rows
//remove the junk added #region Remove Junk List<SampleData> items = new List<SampleData>(); if (radioButton1.Checked) { items = _sampleData.Where(o => o.ID > 5 && o.ID < 11).ToList(); } else if (radioButton2.Checked) { items = _sampleData.Where(o => o.ID > 20 && o.ID < 26).ToList(); } foreach (SampleData sd in items) { _sampleData.Remove(sd); }
ultraDataSource1.Rows.SetCount(_sampleData.Count); ultraDataSource1.ResetCachedValues(); #endregion
this.ultraGrid1.ActiveRow = this.ultraGrid1.Rows[row.Index]; var activeIndex = ultraGrid1.ActiveRow.Index; this.ultraGrid1.Rows[activeIndex].Activate(); this.ultraGrid1.Rows[activeIndex].Selected = true;
this.ultraGrid1.ActiveRowScrollRegion.FirstRow = this.ultraGrid1.Rows[Math.Abs(row.Index - rowIndex)];
this.ultraGrid1.ResumeLayout();
updateValues();
button1.Enabled = true; }