在 WinForm DataGridView 中,初始化时会自动选择第一行,当我试图关闭该功能时,这让我很困扰。转向 WPF DataGrid,微软似乎已经决定关闭了这个功能,我认为这是一件好事。然而,我现在很难启用此功能。对于某些DataGrid,我希望在通过数据绑定填充网格后自动选择第一行。网络上有一些建议,但我无法使其正常工作。希望在这里能够更好地解决问题。
设置 IsSynchronizedWithCurrentItem = "true"
。
编辑:
回应您的评论,我假设您的 DataGrid 的 SelectionUnit 设置为 "Cell",是吗?好的,我不确定这是否是最佳解决方案,但您可以在 DataGrid 上处理 Loaded 事件,并在代码中手动设置所选单元格。因此,您将拥有类似以下内容的东西:
<DataGrid x:Name="dg" AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True"
SelectedCellsChanged="dg_SelectedCellsChanged" SelectionUnit="Cell"
Loaded="dg_Loaded">
...
</DataGrid>
事件处理器:
private void dg_Loaded(object sender, RoutedEventArgs e)
{
if ((dg.Items.Count > 0) &&
(dg.Columns.Count > 0))
{
//Select the first column of the first item.
dg.CurrentCell = new DataGridCellInfo(dg.Items[0], dg.Columns[0]);
dg.SelectedCells.Add(dg.CurrentCell);
}
}
注意,这仅在DataGrid.SelectionUnit设置为"Cell"时才起作用。否则,我认为它会抛出异常。<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Button Click="Button_Click">Reset</Button>
<DataGrid x:Name="dg" AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True"
SelectionUnit="Cell"
DataContextChanged="dg_DataContextChanged"
ItemsSource="{Binding Items}"
Loaded="dg_Loaded">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding}"/>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</Window>
代码后端:
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.LoadItems();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.LoadItems();
}
private void LoadItems()
{
this.DataContext = new { Items = new List<string> { "Item1", "Item2", "Item3" } };
this.SelectFirstItem();
}
private void dg_Loaded(object sender, RoutedEventArgs e)
{
SelectFirstItem();
}
void SelectFirstItem()
{
if ((dg.Items.Count > 0) &&
(dg.Columns.Count > 0))
{
//Select the first column of the first item.
dg.CurrentCell = new DataGridCellInfo(dg.Items[0], dg.Columns[0]);
dg.SelectedCells.Add(dg.CurrentCell);
}
}
private void dg_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
this.SelectFirstItem();
}
}
}
您可以在DataGrid.Loaded事件中始终执行此操作。只需获取第一行,并使该行触发选择事件。
void MyGridLoaded(...) {
DataGridRow r = yourGrid.ItemContainergenerator.ContainerFromIndex(0) as DataGridRow;
if(r != null) {
r.IsSelected = false;
r.IsSelected = true;
}
}
this.dataGrid.SelectionMode = DataGridSelectionMode.Single;
// Selects the 4th row.
this.dataGrid.SelectedIndex = 3;
我很高兴地报告,我通过ItemContainerGenerator.StatusChanged
事件找到了解决这个问题的方法。
dataGrid.ItemContainerGenerator.StatusChanged += new EventHandler(ItemContainerGenerator_StatusChanged);
void ItemContainerGenerator_StatusChanged(object sender, EventArgs e)
{
if (dataGrid.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
{
dataGrid.SelectedIndex = 0;
}
}
当使用状态 ContainersGenerated 触发此事件时,dataGrid 将完全初始化。对我而言,这更像是 WinForm 中 DataGridView 的 DataBindingComplete 事件。如果是这样,那么 "DataContextChanged
" 事件应该真正被称为 "DataContextChanging
" 事件。
这是受到我意外发现的一个帖子 here 的启发,我当时正在寻找其他线索。