2013-10-07 18 views

risposta

12

Fare riferimento alla pagina DataGrid Class su MSDN. Da quella pagina:

Selezione

Per default, l'intera riga viene selezionata quando un utente seleziona una cella in un DataGrid e un utente può selezionare più righe. È possibile impostare la proprietà per specificare se un utente può selezionare celle, righe complete o entrambe. Impostare la proprietà SelectionUnit per specificare se possono essere selezionate più righe o celle o solo singole righe o celle.

È possibile ottenere informazioni sulle celle selezionate dalla proprietà SelectedCells. È possibile ottenere informazioni sulle celle per le quali è stata modificata la selezione nel SelectedCellsChangedEventArgs dell'evento SelectedCellsChanged. Chiama i metodi SelectAllCells o UnselectAllCells per selezionare o deselezionare a livello di codice tutte le celle. Per ulteriori informazioni, vedere Comportamento predefinito della tastiera e del mouse nel controllo DataGrid.

Ho aggiunto collegamenti alle proprietà pertinenti per voi, ma sono fuori dal tempo ora, quindi spero che possiate seguire i collegamenti per ottenere la vostra soluzione.

+0

Nella misura in cui si fornisce a SO e che è grande, questo non è davvero una risposta ma una risposta "Guardalo qui". – OmegaMan

+1

Nessun argomento da parte mia. – Sheridan

8

Se si seleziona una sola cella il contenuto delle celle quindi essere selezionato come questo

var cellInfo = dataGrid1.SelectedCells[0]; 

var content = cellInfo.Column.GetCellContent(cellInfo.Item); 

Qui contenuti sarà il vostro celle selezionate valore

E se si selezionano più celle, allora si può fare come questo

var cellInfos = dataGrid1.SelectedCells; 

var list1 = new List<string>(); 

foreach (DataGridCellInfo cellInfo in cellInfos) 
{ 
    if (cellInfo.IsValid) 
    { 
     //GetCellContent returns FrameworkElement 
     var content= cellInfo.Column.GetCellContent(cellInfo.Item); 

     //Need to add the extra lines of code below to get desired output 

     //get the datacontext from FrameworkElement and typecast to DataRowView 
     var row = (DataRowView)content.DataContext; 

     //ItemArray returns an object array with single element 
     object[] obj = row.Row.ItemArray; 

     //store the obj array in a list or Arraylist for later use 
     list1.Add(obj[0].ToString()); 
    } 
} 
+0

Una piccola aggiunta alla soluzione a cella singola, il contenuto dovrebbe essere modificato in Textblock come questo var content = (cellInfo.Column.GetCellContent (cellInfo.Item) come TextBlock) .Text; –

12

Quando ho affrontato questo problema, mi sono avvicinato così: ho creato un DataRowView, ha afferrato la colonna di ind ex, e poi utilizzato che della riga ItemArray

DataRowView dataRow = (DataRowView)dataGrid1.SelectedItem; 
int index = dataGrid1.CurrentCell.Column.DisplayIndex; 
string cellValue = dataRow.Row.ItemArray[index].ToString(); 
+2

Funziona solo quando 'SelectionUnit' è impostato su' DataGridSelectionUnit.FullRow' –

+0

@Bahman_Aries Vedere la mia risposta quando 'SelectionUnit' è' Cell'. –

+0

Grazie mille joj hai risolto il mio grosso problema! – DumpsterDiver

1

Questi sono 2 metodi che possono essere utilizzati per prendere un valore dalla riga selezionata

/// <summary> 
    /// Take a value from a the selected row of a DataGrid 
    /// ATTENTION : The column's index is absolute : if the DataGrid is reorganized by the user, 
    /// the index must change 
    /// </summary> 
    /// <param name="dGrid">The DataGrid where we take the value</param> 
    /// <param name="columnIndex">The value's line index</param> 
    /// <returns>The value contained in the selected line or an empty string if nothing is selected</returns> 
    public static string getDataGridValueAt(DataGrid dGrid, int columnIndex) 
    { 
     if (dGrid.SelectedItem == null) 
      return ""; 
     string str = dGrid.SelectedItem.ToString(); // Take the selected line 
     str = str.Replace("}", "").Trim().Replace("{", "").Trim(); // Delete useless characters 
     if (columnIndex < 0 || columnIndex >= str.Split(',').Length) // case where the index can't be used 
      return ""; 
     str = str.Split(',')[columnIndex].Trim(); 
     str = str.Split('=')[1].Trim(); 
     return str; 
    } 

    /// <summary> 
    /// Take a value from a the selected row of a DataGrid 
    /// </summary> 
    /// <param name="dGrid">The DataGrid where we take the value.</param> 
    /// <param name="columnName">The column's name of the searched value. Be careful, the parameter must be the same as the shown on the dataGrid</param> 
    /// <returns>The value contained in the selected line or an empty string if nothing is selected or if the column doesn't exist</returns> 
    public static string getDataGridValueAt(DataGrid dGrid, string columnName) 
    { 
     if (dGrid.SelectedItem == null) 
      return ""; 
     for (int i = 0; i < columnName.Length; i++) 
      if (columnName.ElementAt(i) == '_') 
      { 
       columnName = columnName.Insert(i, "_"); 
       i++; 
      } 
     string str = dGrid.SelectedItem.ToString(); // Get the selected Line 
     str = str.Replace("}", "").Trim().Replace("{", "").Trim(); // Remove useless characters 
     for (int i = 0; i < str.Split(',').Length; i++) 
      if (str.Split(',')[i].Trim().Split('=')[0].Trim() == columnName) // Check if the searched column exists in the dataGrid. 
       return str.Split(',')[i].Trim().Split('=')[1].Trim(); 
     return str; 
    } 
4

Se SelectionUnit="Cell" provate questo:

string cellValue = GetSelectedCellValue(); 

Dove:

public string GetSelectedCellValue() 
    { 
     DataGridCellInfo cellInfo = MyDataGrid.SelectedCells[0]; 
     if (cellInfo == null) return null; 

     DataGridBoundColumn column = cellInfo.Column as DataGridBoundColumn; 
     if (column == null) return null; 

     FrameworkElement element = new FrameworkElement() { DataContext = cellInfo.Item }; 
     BindingOperations.SetBinding(element, TagProperty, column.Binding); 

     return element.Tag.ToString(); 
    } 

sembra che non dovrebbe essere così complicato, lo so ...

Edit: Questo non sembra di lavorare su DataGridTemplateColumn colonne di tipo. Si potrebbe anche provare questo se le righe sono costituiti da una classe personalizzata e hai assegnato un percorso membro sorta:

public string GetSelectedCellValue() 
    { 
     DataGridCellInfo cells = MyDataGrid.SelectedCells[0]; 

     YourRowClass item = cells.Item as YourRowClass; 
     string columnName = cells.Column.SortMemberPath; 

     if (item == null || columnName == null) return null; 

     object result = item.GetType().GetProperty(columnName).GetValue(item, null); 

     if (result == null) return null; 

     return result.ToString(); 
    } 
1

Ho lottato con questo per molto tempo! (Utilizzando VB.NET) Fondamentalmente si ottiene l'indice di riga e l'indice di colonna della cella selezionata, e quindi si usa quello per accedere al valore.

Private Sub LineListDataGrid_SelectedCellsChanged(sender As Object, e As SelectedCellsChangedEventArgs) Handles LineListDataGrid.SelectedCellsChanged 

    Dim colInd As Integer = LineListDataGrid.CurrentCell.Column.DisplayIndex 

    Dim rowInd As Integer = LineListDataGrid.Items.IndexOf(LineListDataGrid.CurrentItem) 

    Dim item As String 

    Try 
     item = LLDB.LineList.Rows(rowInd)(colInd) 
    Catch 
     Exit Sub 
    End Try 

End Sub 

End Class

1
//Xaml Code 
<DataGrid.Columns> 
<DataGridTextColumn Binding="{Binding Path=Date, Converter={StaticResource dateconverter}, Mode=OneWay}" Header="Date" Width="100"/> 
<DataGridTextColumn Binding="{Binding Path=Prescription}" Header="Prescription" Width="900"/> 
</DataGrid.Columns> 

//C# Code 
DataRowView row = (DataRowView)grid1.SelectedItem; 
MessageBox.Show(row["Prescription"].toString() + " " + row["Date"].toString()); 

Come WPF fornisce vincolante nel DataGrid, questo dovrebbe essere piuttosto trasparente. Tuttavia, il seguente metodo funziona solo se è stato utilizzato SQLDataAdapter e fornito un percorso di associazione alle colonne DataGrid. Per es. Diciamo che il datagrid di cui sopra è denominato grid1, che ha auto generare colonne impostate su false e utilizza l'associazione per associare i nomi delle colonne alle intestazioni. In questo caso, usiamo la variabile 'row' di tipo 'DataRowView' e memorizziamo la riga selezionata al suo interno. Ora, usa i tuoi percorsi di rilegatura e fai riferimento a singole colonne della riga selezionata. Spero che questo aiuti! Saluti!

PS: Funziona se SelectionUnit = 'Row'

0

Ok dopo aver fatto il reverse engineering e un piccolo tocco di polvere di riflessione, può fare questa operazione su SelectedCells (in qualsiasi punto) per ottenere tutti (a prescindere dalla selezionato su una riga o più righe) i dati da uno a molti celle selezionate:

MessageBox.Show(

string.Join(", ", myGrid.SelectedCells 
         .Select(cl => cl.Item.GetType() 
              .GetProperty(cl.Column.SortMemberPath) 
              .GetValue(cl.Item, null))) 

       ); 

ho provato questo su testo (stringa) campi solo se un campo DateTime deve restituire un valore l'iniziato ToString(). Si noti inoltre che lo SortMemberPath non è lo stesso di Header, pertanto è necessario fornire sempre la proprietà corretta da cui riflettere.

<DataGrid ItemsSource="{Binding MyData}"      
      AutoGenerateColumns="True" 
      Name="myGrid" 
      IsReadOnly="True" 
      SelectionUnit="Cell" 
      SelectionMode="Extended"> 
0

sto estendendo la soluzione Rushi a seguire (che ha risolto l'enigma per me)

var cellInfo = Grid1.SelectedCells[0]; 
var content = (cellInfo.Column.GetCellContent(cellInfo.Item) as TextBlock).Text;