如何以编程方式在WPF DataGrid中选择行或单元格?

时间:2010-10-01 02:36:50

标签: c# wpf select datagrid row

在WinForm DataGridView中,它会在初始化时自动选择第一行。当我试图关掉这个功能时,它让我抓狂。转移到WPF DataGrid,似乎微软决定关闭这个功能,这是我认为的好事。但是,我现在很难启用此功能。对于某些DataGrid,我希望在通过数据绑定填充网格后自动选择第一行。互联网上有一些建议,但我无法做到这一点。我希望在这里有更好的运气。

4 个答案:

答案 0 :(得分:9)

设置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”时才有效。否则,我相信它会抛出异常。

<强> EDIT2:

XAML:

<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();
        }
    }
}

答案 1 :(得分:3)

您可以在DataGrid.Loaded事件中一致地执行此操作。只需获取第一行并让行触发选择事件。

void MyGridLoaded(...) {
DataGridRow r = yourGrid.ItemContainergenerator.ContainerFromIndex(0) as DataGridRow;
  if(r != null) {
     r.IsSelected = false;
     r.IsSelected = true;
  }

} 

我不确定这是一个错误,因为在加载控件之前,可能无法保证您的对象可以触发选择事件。不知道。

答案 2 :(得分:1)

我很高兴通过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的启发。

答案 3 :(得分:0)

你可以试试这个。

        this.dataGrid.SelectionMode = DataGridSelectionMode.Single;

        // Selects the 4th row.
        this.dataGrid.SelectedIndex = 3;