我正在使用模型来选择DataGrid中的项,如下所示:
public ObservableCollection<MyModel> Models{
get {return m_Models; }
}
public MyModel SelectedModel
{
get{ return m_SelectedModel; }
set{
m_SelectedModel = value;
}
NotifyPropertyChanged("SelectedModel");
NotifyPropertyChanged("Models");
}
这两个公共属性在模型中,即窗口的数据上下文。在XAML中,Observable Collection绑定到数据网格,SelectedItem绑定到SelectedModel:
<DataGrid x:Name="MyDataGrid" AutoGenerateColumns="False" IsReadOnly="True" CanUserResizeColumns="True" CanUserAddRows="False" CanUserSortColumns="True"
SelectionMode="Single" SelectionChanged="DataGrid_SelectionChanged" ItemsSource="{Binding Models}"
CanUserResizeRows="False" IsTextSearchEnabled="True" RowHeaderWidth="0" SelectedItem="{Binding SelectedModel, Mode=TwoWay, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True}" Grid.ColumnSpan="2" Margin="0,0,-0.4,-0.4">
因此,每当我更改SelectedModel时,数据网格中的SelectedItem都会更新。这工作得很好,我已经能够基于SelectedItem填充其他数据。确实,在设置SelectedModel时会调用我的DataGrid_SelectionChanged事件处理程序。
但是,每当我选择一个新项目时,我都希望数据网格自动滚动以显示SelectedItem。我尝试了多种方法使它正常工作,但无济于事。这是我尝试过的一些事情(已确认此功能已通过调试器调用):
private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if(MyDataGrid.SelectedItem != null)
{
//All 3 of these have been tried separately and do not work
MyDataGrid.ScrollIntoView(MyDataGrid.SelectedItem);
MyDataGrid.ScrollIntoView(MyDataGrid.Items[MyDataGrid.SelectedIndex]);
MyDataGrid.ScrollIntoView(_model.SelectedModel); //Didn't expect this one to work but just want to show that I'm trying things out here
}
}
我已经查看了ScrollIntoView的其他问题,但似乎都无法解决我的问题。我将不胜感激。谢谢。
答案 0 :(得分:0)
不知道为什么它对您不起作用,但是它肯定可以正常工作。在下面查看演示应用程序代码:
XAML
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid x:Name="MyDataGrid" AutoGenerateColumns="False" IsReadOnly="True" CanUserResizeColumns="True" CanUserAddRows="False" CanUserSortColumns="True"
SelectionMode="Single" SelectionChanged="DataGrid_SelectionChanged" ItemsSource="{Binding Items}"
CanUserResizeRows="False" IsTextSearchEnabled="True" RowHeaderWidth="0" SelectedItem="{Binding SelectedItem, Mode=TwoWay, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True}"
Grid.ColumnSpan="2" Margin="0,0,-0.4,-0.4">
<DataGrid.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red" />
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey }" Color="Red" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn Header="Id" Binding="{Binding Id}" />
<DataGridTextColumn Header="Name" Binding="{Binding Name}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
类文件
using System;
using System.ComponentModel;
using System.Linq;
using System.Timers;
using System.Windows;
namespace WpfApplication1
{
public class Model
{
public int Id { get; set; }
public string Name { get; set; }
}
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private readonly Model[] items;
public ViewModel()
{
items = Enumerable.Range(1, 101)
.Select(x => new Model
{
Id = x,
Name = $"Item {x}"
})
.ToArray();
}
public Model[] Items => items;
private Model selectedItem;
public Model SelectedItem
{
get { return selectedItem; }
set
{
selectedItem = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItem)));
}
}
}
public partial class MainWindow : Window
{
private readonly Timer timer;
private readonly ViewModel model;
private readonly Random random;
public MainWindow()
{
InitializeComponent();
model = new ViewModel();
random = new Random();
timer = new Timer(2000);
DataContext = model;
timer.Elapsed += Timer_Elapsed;
timer.Start();
}
private void Timer_Elapsed(Object sender, ElapsedEventArgs e)
{
var index = random.Next(model.Items.Length);
model.SelectedItem = model.Items[index];
}
private void DataGrid_SelectionChanged(Object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
if (MyDataGrid.SelectedItem != null)
{
MyDataGrid.ScrollIntoView(MyDataGrid.SelectedItem);
}
}
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
timer.Stop();
timer.Dispose();
}
}
}
在我看来,您的代码正在执行某些操作,可能会阻止框架滚动网格。
答案 1 :(得分:0)
我能够使ScrollIntoView工作,但是我需要将ScrollToView函数放入数据网格的Loaded回调中。以下是解决此问题的示例:
private void DataGrid_Loaded(object sender, RoutedEventArgs e)
{
if(MyDataGrid.SelectedItem != null)
{
MyDataGrid.ScrollIntoView(MyDataGrid.SelectedItem);
}
}
我的猜测是数据网格没有完全加载到SelectionChanged事件上,因此没有滚动到正确的位置。