У нас есть ListBox, который имеет много объектов. Объекты вставляются в ListBox через ObservableCollection. Некоторые из этих объектов могут быть отредактированы прямо в ListBox. Однако, если объект добавляется в индексе <индекс отредактированного объекта, все содержание движений вниз ListBox.
То, что мы хотели бы сделать, следующее: если бы объект находится в режиме редактирования, мы хотели бы заморозить его позицию по экрану. Хорошо, если объекты добавляются к набору и UI вокруг изменений объекта. Но положение объекта должно остаться постоянным на экране.
Единственной вещью, которую я смог сделать до сих пор, является присоединение к событию ScrollChanged и, самое большее, используйте или методы BringIntoView или ScrollIntoView, чтобы гарантировать, что объект всегда отображается где-нибудь в UI, но я не могу заблокировать вниз его положение.
Кто-либо убрал что-то вроде этого и справку?
Вы всегда можете принудительно добавить предметы в конец вашей коллекции. В противном случае, я думаю, вы на правильном пути, прокручивая ScrollViewer. При входе в «режим редактирования» отслеживайте текущее смещение по горизонтали.
ScrollViewer sv = listBox.GetScrollViewer();
double indexPos = sv.HorizontalOffset;
Однако я думаю, вам лучше присоединиться к событию ObservableCollection.CollectionChanged. Когда событие срабатывает, проверьте, было ли новое значение вставлено над вашим элементом «режим редактирования». Если это так, запустите следующий код.
ScrollViewer sv = listBox.GetScrollViewer();
sv.ScrollToHorizontalOffset(indexPos+1); // This will obviously require an offset
Проблема в том, что вы просто не хотите, чтобы он двигался? Или проблема заключается в том, что вы ссылались на указанный элемент по его порядковому номеру, и изменение индекса вызывает другие проблемы, когда вы применяете изменения (например, применяете их к элементу, который сейчас находится в предыдущем индексе)?
Если проблема в что изменение индекса вызывает проблемы в коде, тогда я бы прекратил использовать индекс и вместо этого получил бы ссылку на объект. Позже вы всегда можете получить индекс предмета, если он вам понадобится.
Я думаю, что следующее может решить вашу проблему:
При входе в режим редактирования сохраните ссылку на редактируемый объект, его индекс в списке и HorizontalOffset ScrollViewer.
В обработчике ObservableCollection.Событие CollectionChanged находит новый индекс объекта, который вы редактируете, если индекс изменился, замените отредактированный элемент тем, который теперь занимает его место (или какой-либо другой логикой, если вы хотите сохранить определенный порядок). Затем, если ScrollViewer.HorizontalOffset изменился, переместите его обратно на указанное смещение.
Это гарантирует, что редактируемый элемент всегда будет оставаться в одном и том же месте в списке и в пользовательском интерфейсе.
Надеюсь, это вам поможет.
Можно ли переключиться на ListView и использовать EnsureVisible?
Если возможно замораживание остальной части списка. Чтобы добавленные элементы не отображались до тех пор, пока редактирование не было завершено или не было экранировано, вы можете попробовать использовать BeginUpdate
и EndUpdate
, чтобы остановить перерисовку ListBox. Я не уверен, как это повлияет на ваш процесс редактирования.