DataGridRows mit gleichem Spalteneintrag markieren
-
Mittwoch, 26. Dezember 2012 19:05
0Versuche seit gerstern abend krampfhaft in eienm DataGrid alle Rows zu markieren, welche in der zweiten Spalte den identischen Text stehen haben.
Genauso soll bei allen Rows wieder die Markierung entfernt werden, wenn die Row markiert ist und geklickt wird. Ich verwende dazu das SelectionChanges-Ereignis. Ich habe den Code beigefügt. Das PRoblem ist eben, das der Code korrekt abgearbeitet wird, aber immer nur die geklickte Zeile markiert wird, obwohl mehrere Zeilen mit gleicher Auftragsnummer vorhanden sind. Woran kann das liegen?
Hier der Code:
private void dg_Visudaten_SelectionChanged(object sender, SelectionChangedEventArgs e) { //// Mehrere DataGridRows dürfen angewählt werden dg_Visudaten.SelectionMode = (DataGridSelectionMode) SelectionMode.Multiple; //// Variable für den Text in der Spalte string auftragsNummer; //if(sender.GetType() != typeof(DataGrid)) // return; //// Ereignis abmelden dg_Visudaten.SelectionChanged -= dg_Visudaten_SelectionChanged; //// Wurde eine DataGridRow neu markiert (ausgewählt)? if(e.AddedItems.Count > 0) { //// Auftragsnummer der neu markierten Zeile auslesen auftragsNummer = ((DataRowView) (e.AddedItems[0])).Row["Auftragsnr"].ToString(); //// Alle Zeilen im DataGrid durchlaufen und auf identische "Auftragsnummer" prüfen. Ist die "Auftragsnummer" identisch, die DataGridRow.IsSelected markieren for (int i = 0; i < dg_Visudaten.Items.Count; i++) { DataGridRow dgRow = (DataGridRow) dg_Visudaten.ItemContainerGenerator.ContainerFromIndex(i); if (((DataRowView)(dg_Visudaten.Items[i])).Row["Auftragsnr"].ToString().Trim() == auftragsNummer) dgRow.IsSelected = true; } } //// Wurde eine DataGridRow die markiert war abgewählt ? if (e.RemovedItems.Count > 0) { //// Auftragsnummer der abgewählten Zeile auslesen auftragsNummer = ((DataRowView)(e.RemovedItems[0])).Row["Auftragsnr"].ToString(); //// Alle Zeilen im DataGrid durchlaufen und auf identische "Auftragsnummer" prüfen. Ist die "Auftragsnummer" identisch, die DataGridRow.IsSelected deselektieren for (int i = 0; i < dg_Visudaten.Items.Count; i++) { DataGridRow dgRow = (DataGridRow)dg_Visudaten.ItemContainerGenerator.ContainerFromIndex(i); if (((DataRowView)(dg_Visudaten.Items[i])).Row["Auftragsnr"].ToString().Trim() == auftragsNummer) dgRow.IsSelected = false; } } //// Ereignis wieder anmelden dg_Visudaten.SelectionChanged += dg_Visudaten_SelectionChanged; }
oema von MSDN
- Typ geändert Robert BreitenhoferMicrosoft Contingent Staff, Moderator Montag, 31. Dezember 2012 13:38 Frage
Alle Antworten
-
Donnerstag, 27. Dezember 2012 10:32
Hallo,
eine mögliche Lösung für eine gebundene DataView:
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Windows; using System.Windows.Controls; namespace ElmarBoye.Samples.Wpf { public partial class GridSelectionWindow : Window { public GridSelectionWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { this.dataGrid1.ItemsSource = CreateSampleTable().DefaultView; this.dataGrid1.SelectionMode = DataGridSelectionMode.Extended; this.dataGrid1.SelectionChanged += dataGrid1_SelectionChanged;; } private DataTable CreateSampleTable() { var table = new DataTable("Tabelle"); table.Columns.AddRange(new[] { new DataColumn("Id", typeof(int)), new DataColumn("Auftragsnr", typeof(string)) }); table.PrimaryKey = new [] { table.Columns["Id"] }; for (int index = 0; index < 10000; index++) { table.Rows.Add(index, (index % 10).ToString()); } table.AcceptChanges(); return table; } private void dataGrid1_SelectionChanged(object sender, SelectionChangedEventArgs e) { const string columnName = "Auftragsnr"; DataGrid grid = sender as DataGrid; Console.WriteLine("SelectionChanged {0} / {1}", grid.SelectedItems.Count, grid.SelectedCells.Count); grid.SelectionChanged -= dataGrid1_SelectionChanged; try { var removedRows = new List<DataRowView>(); var addedRows = new List<DataRowView>(); if (e.RemovedItems != null && e.RemovedItems.Count > 0) { // abgewählte Werte (eindeutig) string[] removedValues = e.RemovedItems.Cast<DataRowView>() .Select(row => row[columnName] as string) .Distinct().ToArray(); // Durchlaufen der ausgewählen Elemente (hier DataRowView) foreach (DataRowView rowView in grid.SelectedItems.Cast<DataRowView>()) { var compareValue = rowView[columnName] as string; if (removedValues.Any(columnValue => String.Compare( columnValue, compareValue, StringComparison.OrdinalIgnoreCase) == 0)) { removedRows.Add(rowView); } } } if (e.AddedItems != null && e.AddedItems.Count > 0) { // neue Werte (eindeutig) string[] addedValues = e.AddedItems.Cast<DataRowView>() .Select((row) => row[columnName] as string) .Distinct().ToArray(); // Durchlaufen der gebundenen DataView var dataView = grid.ItemsSource as DataView; foreach (DataRowView rowView in dataView) { var compareValue = rowView[columnName] as string; if (addedValues.Any(columnValue => String.Compare( columnValue, compareValue, StringComparison.OrdinalIgnoreCase) == 0)) { // ggf. Überschneidungen entfernen removedRows.Remove(rowView); if (!grid.SelectedItems.Contains(rowView)) addedRows.Add(rowView); } } } // alte abwählen bzw. neue auswählen removedRows.ForEach(row => grid.SelectedItems.Remove(row)); addedRows.ForEach(row => grid.SelectedItems.Add(row)); } finally { grid.SelectionChanged += dataGrid1_SelectionChanged; } } } }Um Probleme durch die Virtualisierung zu umgehen, arbeitet die Auswahl über die SelectedItems und versucht nicht IsSelected zu verändern. Kleiner Nachteil bei größeren Treffer-Mengen: Es ist nicht gerade das schnellste - wobei ich fürs Beispiel etwas übertrieben haben dürfte ;)
Gruß Elmar
- Als Antwort markiert Robert BreitenhoferMicrosoft Contingent Staff, Moderator Montag, 31. Dezember 2012 13:38
-
Sonntag, 30. Dezember 2012 00:17Hallo, danke für die Info, das hat mit weitergeholfen.
oema von MSDN

