Решение довольно простое.Используйте сетку, унаследованную от DataGrid
, переопределите OnIsKeyboardFocusWithinChanged()
и НЕ вызывайте base.OnIsKeyboardFocusWithinChangedand()
:
public class MyGrid : DataGrid
{
protected override void OnIsKeyboardFocusWithinChanged(DependencyPropertyChangedEventArgs e)
{
// Do not call base.OnIsKeyboardFocusWithinChanged(e);
}
}
Производительность должна быть намного лучше.По крайней мере, для вашего примера кода:).
Следующая трассировка стека является причиной узкого места:
0012dd90 58cd5818 System.Windows.DependencyObject.LookupEntry(Int32)
0012ddb0 58cd923b System.Windows.DependencyObject.GetValueSource(System.Windows.DependencyProperty, System.Windows.PropertyMetadata, Boolean ByRef, Boolean ByRef, Boolean ByRef, Boolean ByRef, Boolean ByRef)
0012dde0 58cd91f2 System.Windows.DependencyObject.GetValueSource(System.Windows.DependencyProperty, System.Windows.PropertyMetadata, Boolean ByRef)
0012de04 56c78477 System.Windows.VisualStateManager.GetVisualStateGroupsInternal(System.Windows.FrameworkElement)
0012de14 56c504e7 System.Windows.VisualStateManager.GoToStateCommon(System.Windows.FrameworkElement, System.Windows.FrameworkElement, System.String, Boolean)
0012de38 56c504ac System.Windows.VisualStateManager.GoToState(System.Windows.FrameworkElement, System.String, Boolean)
0012de50 5753506a System.Windows.Controls.DataGridCell.ChangeVisualState(Boolean)
0012de64 56c5012c System.Windows.Controls.Control.UpdateVisualState(Boolean)
0012de74 575353fa System.Windows.Controls.DataGridCell.NotifyPropertyChanged(System.Windows.DependencyObject, System.String, System.Windows.DependencyPropertyChangedEventArgs, System.Windows.Controls.DataGridNotificationTarget)
0012debc 5753b4d0 System.Windows.Controls.Primitives.DataGridCellsPresenter.NotifyPropertyChanged(System.Windows.DependencyObject, System.String, System.Windows.DependencyPropertyChangedEventArgs, System.Windows.Controls.DataGridNotificationTarget)
0012df04 5752a1d5 System.Windows.Controls.DataGridRow.NotifyPropertyChanged(System.Windows.DependencyObject, System.String, System.Windows.DependencyPropertyChangedEventArgs, System.Windows.Controls.DataGridNotificationTarget)
0012df4c 5751becd System.Windows.Controls.DataGrid.NotifyPropertyChanged(System.Windows.DependencyObject, System.String, System.Windows.DependencyPropertyChangedEventArgs, System.Windows.Controls.DataGridNotificationTarget)
0012dfa4 57512d98 System.Windows.Controls.DataGrid.OnIsKeyboardFocusWithinChanged(System.Windows.DependencyObject, System.Windows.DependencyPropertyChangedEventArgs)
Диспетчер визуальных состояний обновляет каждую ячейку в событии IsKeyboardFocusWithinChanged
.
Кстати, достаточно интересно, если вы используете ILSpy для декомпиляции DataGrid.OnIsKeyboardFocusWithinChanged()
, вы не найдете его там, как если бы он не переопределял поведение по умолчанию из базового класса. WinDbg показывает совершенно противоположное.
Надеюсь, это ответит на ваш вопрос, но я могу легко предвидеть еще много проблем без включенной виртуализации.
ОБНОВЛЕНИЕ Как найти причину?Просто подключите с помощью отладчика к вашему процессу, и каждый раз, когда вы видите, что медлительность врывается в отладчик, проверяйте трассировку стека потока пользовательского интерфейса.Если часто появляется один и тот же след стека - это, вероятно, ваш злодей.Я использовал WinDbg , чтобы отследить это.Отладчик VS также должен быть эффективным.