У меня есть следующий класс модели представления:
public class ViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
private bool _isSelected;
public bool IsSelected {
get => _isSelected;
set {
if (value == _isSelected) { return; }
_isSelected = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSelected)));
}
}
public int Data { get; }
public ViewModel(int data) => Data = data;
}
и следующий вид:
<Window x:Class="MVVMScrollIntoView.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DataGrid Name="dg">
<DataGrid.RowStyle>
<Style TargetType="DataGridRow">
<Setter Property="IsSelected" Value="{Binding IsSelected}"/>
</Style>
</DataGrid.RowStyle>
</DataGrid>
</Window>
Я установил ItemsSource
DataGrid в коде позади какследует:
var data = Enumerable.Range(1, 100).Select(x => new ViewModel(x)).ToList();
dg.ItemsSource = data;
Выбор / отмена выбора строк в сетке данных распространяются на экземпляры модели представления, а изменения кода на свойство IsSelected
модели представления переносятся обратно в сетку данных.
Но я хочу, чтобы, когда свойство IsSelected
было установлено с помощью кода в модели представления:
data[79].IsSelected = true;
выбранная строка сетки данных также прокручивалась в представление, предположительно, с использованием сетки данных ScrollIntoView
method.
Моей первоначальной мыслью было прослушивание в представлении кода для события SelectionChanged
:
dg.SelectionChanged += (s, e) => dg.ScrollIntoView(dg.SelectedItem);
Но это не работает, так как SelectionChanged
срабатывает только на видимых элементах, когда включена виртуализация.
Отключение виртуализации - это успешный обходной путь:
<DataGrid Name="dg" EnableRowVirtualization="False">
...
, но я беспокоюсь о влиянии на производительность для больших списков (20K +предметы), поэтому я бы предпочел не делать этогос.
Как MVVM это делает?