Question

I'm using a PropertyGrid in a tool app to show a window to monitor an object in a remote app. Every second or so I get an update from the app with the state of any members that have changed, and I update the grid. I call Refresh() to make the changes take. This all works pretty well except one thing.

Say the object is too tall to fit in the grid so there's a scrollbar. The user has selected a grid item but has also scrolled up above it so that the selected item is below the bottom of the control.

The problem is that on Refresh() the control automatically scrolls the grid item into view (strangely it doesn't do this when the item is above the top of the control).

I'm looking for a way to either prevent this, or to save state, do the Refresh(), and then set it back. I tried getting the underlying VScrollBar in the PropertyGridView inside the PropertyGrid, and messing with "Value", but it doesn't stay permanently set. Always pops back so the item is in view.

Deselecting the item during scrolling is my fallback (the auto scroll-into-view doesn't happen with no selected grid item) but it hurts the usability a little so I'm looking for another way.

Anyone run into something similar?

Was it helpful?

Solution

This is not possible in the MS PropertyGrid. This component has too many unaccessible internals to give you the flexibility you are requesting and as you realized yourself it is not consistent (you have the issue for a property below the grid but not when it is above). That's why I created Smart PropertyGrid.Net. If a commercial product is an option for you, this grid has the option to store property states and restore them after you made an action on the grid (like Refresh()) without any flicker.

OTHER TIPS

I`ve found an interesting hack:

you can manually select the grid items you changed and they will refresh :)

var panProp = categ.GridItems[3];
var tiltProp = categ.GridItems[4];
panProp.Select();
tiltProp.Select();

So I select items I need and than move the selection back

For me the following made the difference:

dont assign a new object.

Simply update the fields of the old object with the new data.

Now, on refresh, my PropertyGrid does not scroll any more, and also shows updated content.

public void SoftRefreshPropertyGrid()
{
     var peMain = propertyGrid.GetType().GetField("peMain", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(propertyGrid)as  System.Windows.Forms.GridItem;
     if (peMain != null)
     {
           var refreshMethod = peMain.GetType().GetMethod("Refresh");
           if (refreshMethod != null)
           {
                  refreshMethod.Invoke(peMain, null);
                  propertyGrid.Invalidate(true);
           }
     }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top