Положение прокрутки PropertyGrid не изменяется при установке - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть PropertyGrid в приложении Windows Forms.Всякий раз, когда изменяется SelectedObject, оно сбрасывает значение VerticalScroll на 0. Мне нужно, чтобы оно оставалось там, где оно было.Код ниже, похоже, ничего не делает.Я пробовал PerformLayout и кучу других решений безуспешно.Есть идеи?

int pos = MyGrid.VerticalScroll.Value;
MyGrid.SelectedObject = SomeDifferentObject;
MyGrid.VerticalScroll.Value = pos;

1 Ответ

0 голосов
/ 28 февраля 2019

Свойство VerticalScroll не относится к классу PropertyGrid.Он ссылается на внутренние свойства элемента управления VScrollBar.Событие Scroll никогда не вызывается.
VScrollBar является дочерним элементом элемента управления System.Windows.Forms.PropertyGridInternal.PropertyGridView, класса, который не доступен напрямую.

Вы можете получить его в любом случае, приведя PropertyGrid к Control или проигнорировав атрибут Browsable(false) свойства Controls PropertyGrid, затем найдите дочерний элемент VScrollBar, сохраните текущее значение и установите его снова после того, как вы получитеизменено свойство SelectedObject.
Обратите внимание, что этот новый элемент управления может иметь количество свойств, отличное от предыдущего, полоса прокрутки будет просто установлена ​​там, где она была раньше.
Чтобы быть более точным точным , вы можете получить количество свойств, показанных до и после установки нового SelectedObject, и выполнить прокрутку относительно .

Здесь я нахожу PropertyGridView по AccessibilityObject.Role, что составляет AccessibleRole.Table, но вы также можете найти его по тексту ("PropertyGridView"):

var vScroll = propertyGrid1.Controls.OfType<Control>()
                           .Where(ctl => ctl.AccessibilityObject.Role == AccessibleRole.Table)
                           .First().Controls.OfType<VScrollBar>().First();
var vScrollValue = vScroll.Value;
propertyGrid1.SelectedObject = [Some Other Object];
vScroll.Value = vScrollValue;

Если вы хотите (как описано выше), переместите полосу прокрутки в ту же относительную позицию, код может выглядеть так:

BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
var propGrid = propertyGrid1.Controls.OfType<Control>()
                            .Where(ctl => ctl.AccessibilityObject.Role == AccessibleRole.Table).First();
var totalProperties = (int)propGrid.GetType().GetField("totalProps", flags).GetValue(propGrid);
var vScroll = propertyGrid1.Controls.OfType<Control>()
                           .Where(ctl => ctl.AccessibilityObject.Role == AccessibleRole.Table)
                           .First().Controls.OfType<VScrollBar>().First();

var vRelativeScroll = vScroll.Value / (float)totalProperties;
propertyGrid1.SelectedObject = [Some Other Object];
totalProperties = (int)propGrid.GetType().GetField("totalProps", flags).GetValue(propGrid);
vScroll.Value = (int)(vRelativeScroll * totalProperties);
...