2009-12-31 10 views

Répondre

5

Vous pouvez faire correspondre ce qui doit être sélectionné en fonction de critères spécifiques à vos besoins et définir simplement la propriété Select de la cellule ou de la ligne sur true/false en fonction de votre correspondance. Voici un exemple simple que vous pouvez déposer dans un projet Winforms nouvellement créé qui illustrera le point. Pour que cet exemple fonctionne, veillez à définir le SelectionMode = FullRowSelect de DataGridView. Si vous souhaitez conserver/réappliquer des sélections de cellules, l'approche sera similaire. Remarque: vous pouvez également conserver une liste d'index de ligne sélectionnés, mais cela n'a généralement aucun sens lors du chargement d'une autre source de données car il est généralement impossible d'établir une correspondance entre les lignes réelles et leur position physique dans les données.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Windows.Forms; 

namespace DataGridViewRetainSelection 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private readonly List<Person> currentPeople = new List<Person>(); 
     private bool dummyToggle = true; 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      SwitchDataSource(); // will just new up the datasource 
     } 

     private void ButtonSwitchDataSourceClick(object sender, EventArgs e) 
     { 
      SwitchDataSource(); 
     } 

     private void SwitchDataSource() 
     { 
      var selectedPeople = (from DataGridViewRow row in dataGridViewPeople.Rows where row.Selected select currentPeople[row.Index]).ToList(); 

      peopleBindingSource.DataSource = null; 

      currentPeople.Clear(); 
      if (dummyToggle) 
      { 
       currentPeople.Add(new Person { Name = "Joel Spolsky" }); 
       currentPeople.Add(new Person { Name = "Jeff Atwood" }); 
       currentPeople.Add(new Person { Name = "Jarrod Dixon" }); 
       currentPeople.Add(new Person { Name = "Geoff Dalgas" }); 
       currentPeople.Add(new Person { Name = "Brent Ozar" }); 
      } 
      else 
      { 
       currentPeople.Add(new Person { Name = "Joel Spolsky" }); 
       currentPeople.Add(new Person { Name = "Jeff Atwood" }); 
       currentPeople.Add(new Person { Name = "Brent Ozar" }); 
      } 

      dummyToggle = !dummyToggle; 

      peopleBindingSource.DataSource = currentPeople; 

      foreach (var person in selectedPeople) 
      { 
       foreach (DataGridViewRow row in dataGridViewPeople.Rows) 
       { 
        if (string.Equals(row.Cells[0].Value, person.Name)) 
        { 
         row.Selected = true; 
        } 
       } 
      } 
     } 
    } 

    public sealed class Person 
    { 
     public string Name { get; set; } 
    } 

} 

Pour mettre en œuvre la même fonctionnalité pour les cellules sélectionnées font quelque chose comme ce qui suit. Je laisse le code précédent si quelqu'un d'autre en avait besoin. Note: Je ne fais que frapper un type anonyme ici, vous aurez probablement besoin de faire quelque chose d'un peu plus sophistiqué en fonction des champs membres, des propriétés, etc. mais le principe général du réglage des cellules sélectionnées est illustré correctement et peut facilement être testé et débogué pour la compréhension j'espère.

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Windows.Forms; 

namespace DataGridViewRetainSelection 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private readonly List<Person> currentPeople = new List<Person>(); 
     private bool dummyToggle = true; 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      dataGridViewPeople.SelectionMode = DataGridViewSelectionMode.CellSelect; 
      SwitchDataSource(); // will just new up the datasource 
     } 

     private void ButtonSwitchDataSourceClick(object sender, EventArgs e) 
     { 
      SwitchDataSource(); 
     } 

     private void SwitchDataSource() 
     { 
      var selectedPeopleAndCells = (from DataGridViewCell cell in dataGridViewPeople.SelectedCells where cell.Selected select new { Person = currentPeople[cell.RowIndex], Cell = cell }).ToList(); 

      peopleBindingSource.DataSource = null; 

      currentPeople.Clear(); 
      if (dummyToggle) 
      { 
       currentPeople.Add(new Person { Name = "Joel Spolsky", Id = 0 }); 
       currentPeople.Add(new Person { Name = "Jeff Atwood", Id = 1 }); 
       currentPeople.Add(new Person { Name = "Jarrod Dixon", Id = 2 }); 
       currentPeople.Add(new Person { Name = "Geoff Dalgas", Id = 3 }); 
       currentPeople.Add(new Person { Name = "Brent Ozar", Id = 4 }); 
      } 
      else 
      { 
       currentPeople.Add(new Person { Name = "Joel Spolsky", Id = 0 }); 
       currentPeople.Add(new Person { Name = "Jeff Atwood", Id = 1 }); 
       currentPeople.Add(new Person { Name = "Brent Ozar", Id = 4 }); 
      } 

      dummyToggle = !dummyToggle; 

      peopleBindingSource.DataSource = currentPeople; 

      foreach (var personAndCell in selectedPeopleAndCells) 
      { 
       foreach (DataGridViewRow row in dataGridViewPeople.Rows) 
       { 
        if (string.Equals(row.Cells[0].Value, personAndCell.Person.Id)) 
        { 
         row.Cells[personAndCell.Cell.ColumnIndex].Selected = true; 
        } 
       } 
      } 
     } 
    } 

    public sealed class Person 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
    } 

} 
+0

Bien fonctionne mais la ligne entière est sélectionnée ... Je voulais conserver des cellules sélectionnées aléatoirement dans la DGV; –

+0

Échantillon de code mis à jour pour illustrer la sélection de cellule. –

+0

S'il vous plaît noter, vous aurez besoin d'un certain type de champ ID pour faire correspondre les anciennes lignes avec les nouvelles lignes avec précision. Espérons que l'exemple rend cela assez clair. –