2010-10-01 6 views
8

Dans WinForm DataGridView, il sélectionne automatiquement la première ligne lors de l'initialisation. Cela m'a rendu fou quand j'ai essayé de désactiver cette fonctionnalité. Passer à WPF DataGrid, il semble que Microsoft a décidé de désactiver cette fonctionnalité, ce qui est une bonne chose je pense. Cependant, j'ai du mal à activer cette fonctionnalité maintenant. Pour certains DataGrid, je veux que la première ligne soit sélectionnée automatiquement après que la grille a été remplie via la liaison de données. Il y a quelques suggestions dans Internet, mais je ne pouvais pas faire ce travail. J'espère avoir plus de chance ici.Comment sélectionner une ligne ou une cellule dans WPF DataGrid par programme?

Répondre

9

Définissez IsSynchronizedWithCurrentItem = "true".

EDIT:

Pour répondre à votre commentaire, je suppose que votre SelectionUnit de DataGrid est réglé sur "Cell", est-il? Bon, je ne suis pas sûr que ce soit la meilleure solution, mais une chose que vous pouvez faire est de gérer l'événement Loaded pour le DataGrid et de définir manuellement la cellule sélectionnée dans le code-behind. Ainsi, vous aurez quelque chose comme ceci:

<DataGrid x:Name="dg" AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True" 
      SelectedCellsChanged="dg_SelectedCellsChanged" SelectionUnit="Cell" 
      Loaded="dg_Loaded"> 
    ... 
</DataGrid> 

gestionnaire d'événements:

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

Notez que cela ne fonctionnera que si le DataGrid.SelectionUnit est réglé sur « Cell ». Sinon, je crois que cela va créer une exception.

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> 

code-behind:

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

Merci beaucoup pour le conseil. Je l'ai juste essayé. Si vous le définissez sur true, la première ligne du DataGrid sera mise en surbrillance, mais pas sélectionnée. J'ai besoin de l'événement SelectedCellsChanged pour être déclenché. Alors, comment faire pour que cet événement soit également renvoyé? – newman

+0

Voir EDIT. J'espère que cela aide. – ASanch

+0

@karmicpuppet: Ce code fonctionne dans l'événement dg_Loaded. Cependant, il fonctionne dans l'événement DataContextChanged.Essentiellement, la même grille est réutilisée. Chaque fois qu'un contexte de données de données est défini, je veux que la première ligne soit sélectionnée automatiquement, ce qui devrait déclencher l'événement SelectedCellsChanged parce que je m'en remets à cela. – newman

0

Vous pouvez essayer cela.

 this.dataGrid.SelectionMode = DataGridSelectionMode.Single; 

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

Celui-ci est pour la sélection de ligne. –

+0

@Avatar: J'ai juste essayé votre suggestion. Il semble avoir le même effet que IsSynchronizedWithCurrentItem. Donc, il met juste en évidence la ligne, mais je ne reçois pas l'événement SelectedCellsChanged. Malheureusement, il n'y a pas d'événement "SelectedRowChanged" ou quelque chose comme ça. Par rapport à WinForm DataGridView, WPF DataGrid a très peu d'événements. – newman

+0

@miliu l'événement SelectedCellsChanged doit être déclenché ne sait pas quel est le problème. J'ai un échantillon ici. S'il vous plaît vérifier cela. Cela pourrait vous donner une idée. http://www.filefactory.com/file/b3bhf1d/n/DataGridCheckBoxSelection.zip –

1

Je suis heureux de signaler que je trouve une solution à ce problème par événement 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; 
      } 
     } 

Il semble que lorsque cet événement est déclenché avec l'état ContainersGenerated, le paramètre dataGrid est entièrement initialisé. Pour moi, cela ressemble plus à l'événement DataBindingComplete de DataGridView dans WinForm. Si c'est le cas, l'événement "DataContextChanged" devrait être appelé "DataContextChanging".

Ceci a été inspiré par un article here que j'ai accidentellement trouvé en cherchant un autre indice.

+0

En fait, je viens de réaliser que l'événement ItemContainerGenerator_StatusChanged pourrait être déclenché trop de fois. Je suis revenu à l'événement DataContextChanged et l'ai fait fonctionner via Dispatcher.BeginInvoke. – newman

3

Vous pouvez le faire de manière cohérente dans l'événement DataGrid.Loaded. Il suffit d'obtenir la première ligne et d'avoir la ligne de feu l'événement de sélection.

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

} 

Je ne suis pas sûr que ce soit un bug parce que vous ne pouvez pas être assuré d'avoir des événements de sélection feu de votre objet jusqu'à ce que le contrôle est chargé. Je ne sais pas

Questions connexes