Таким образом, я нашел решение, которое работает довольно хорошо, я не уверен, что это лучший маршрут принять, но это, кажется, работает хорошо.
В методе ArrangeOverride при переходе по дочерним элементам я делаю следующее.
var listViewItem = child as ListViewItem;
if (listViewItem != null)
{
listViewItem.Selected -= ListViewItemSelected;
listViewItem.Selected += ListViewItemSelected;
}
В MeasureOverride я сделать вызов CleanUpItems здесь нам нужно будет отказаться от выбранного события.
var listViewItem = children[i] as ListViewItem;
if (listViewItem != null)
{
listViewItem.Selected -= ListViewItemSelected;
}
Я также добавил следующие три функции.
private void ListViewItemSelected(object sender, RoutedEventArgs e)
{
var listViewItem = sender as ListViewItem;
if(listViewItem == null) return;
var content = listViewItem.Content as CollectionViewGroup;
if(content != null) return; //item is a group header dont click
var items = ItemContainerGenerator as ItemContainerGenerator;
if(items == null) return;
BringIndexIntoView(items.IndexFromContainer(listViewItem));
listViewItem.Focus();
}
protected override void BringIndexIntoView(int index)
{
var offset = GetOffsetForFirstVisibleIndex(index);
SetVerticalOffset(offset.Height);
}
private Size GetOffsetForFirstVisibleIndex(int index)
{
int childrenPerRow = CalculateChildrenPerRow(_extent);
var actualYOffset = ((index/childrenPerRow) * ChildDimension.Height) - ((ViewportHeight - ChildDimension.Height)/2);
if (actualYOffset < 0)
{
actualYOffset = 0;
}
Size offset = new Size(_offset.X, actualYOffset);
return offset;
}
Функция GetOffsetForFirstVisibleIndex, вероятно, варьируются в зависимости от реализации, но это должно быть достаточно информации, если кто-то еще возникают проблемы придумывают решения.
Можем ли мы увидеть код для вашей 'Custom Panel'? –
@RohitVats Я добавил ссылку на источник Panel. – OriginalMoose
У меня такая же проблема сейчас. Любые новости об этом? – ygoe