2017-10-04 3 views
0

J'ai un DataGrid implémenté dans une fenêtre WPF à l'intérieur d'un VSTO-AddIn, qui est censé prévisualiser des données à l'utilisateur avant qu'il ne soit collé à une feuille Excel existante. Le CanUserSortColumns-Property est défini sur true, afin que l'utilisateur puisse réorganiser les colonnes avant qu'elles ne soient lues et collées sur la feuille. Cependant, lorsque j'ai lu le DataRows à partir du DataGrid, comme indiqué ci-dessous, les colonnes sont de retour dans leur position d'origine.Comment sauvegarder les positions de colonnes réarrangées lors de la lecture d'un DataGrid?

object[,] dataArray = new object[allRows, allCols]; 

     for (int r = 0; r < allRows; r++) 
     { 
      DataRow row = ClientGrid.Rows[r]; 
      for (int c = 0; c < allCols; c++) 
      { 
       dataArray[r, c] = row[c]; 
      } 
     } 

Voici ma question: Est-il possible de résoudre ce problème de la manière rapide ou tout au moins de suivre les changements des indices d'affichage de la colonne afin de réorganiser l'ordre des colonnes dans le code à chaque changement de l'affichage des colonnes commande?

J'ai déjà essayé de travailler sur quelque chose avec la propriété DisplayIndex mais je n'ai pas vraiment compris les chiffres qu'elle recrache.

+0

J'ai eu le même problème il y a un moment à l'aide DataGrid, DataSource et DataBinding. J'ai abandonné DataGrid et utilisé un ListView à la place. Mais si vous avez besoin d'éditer les cellules alors le 'ItemsControl 'WPF serait une meilleure solution. – Bijan

Répondre

0

je fini par faire ce qui suit:

  1. Lecture de la DisplayIndex-Property et la position initiale de chaque colonne et ordonnant les tuples par le DisplayIndex-Property après

    var columnIndices = new List<Tuple<int,int>>(); 
    var colCounter = 0; 
    
    foreach (var col in myDataGrid.Columns) 
    { 
        columnIndices.Add(Tuple.Create(col.DisplayIndex, colCounter)); 
        colCounter += 1; 
    } 
    
    var sortedColumns = columnIndices.OrderBy(x => x.Item1).ToList();   
    
  2. Cre en remplissant un DataTable vide et en y ajoutant les colonnes originales DataGrid's. Ensuite, j'ai mis les nouvelles cellules DataTable'sDataRow's égales aux cellules du DataRows de l'original DataGrid.

    var myDataTable = new DataTable(); 
    
    foreach (var index1 in sortedColumns) 
    { 
        var columnName = myDataGrid.Columns[index1.Item2].ColumnName; 
        myDataTable.Columns.Add(columnName, myDataGrid.Columns[index1.Item2].DataType); 
    } 
    
    foreach (DataRow dr in myDataGrid.Rows) 
    { 
        var itemArray = new object[allCols]; 
        var indexer = 0; 
    
        foreach (var index2 in sortedColumns) 
        { 
         itemArray[indexer] = dr[index2.Item2]; 
         indexer += 1; 
        } 
    
        myDataTable.Rows.Add(itemArray); 
    } 
    
0

Vous pouvez commander les colonnes par la réflexion de la propriété DisplayIndex et utiliser pour exporter les valeurs en utilisant la réflexion, par exemple .:

public static void ExportUsingRefection(this DataGrid grid) 
{ 
    if (grid.ItemsSource == null || grid.Items.Count.Equals(0)) 
     throw new InvalidOperationException("You cannot export any data from an empty DataGrid."); 

    IEnumerable<DataGridColumn> columns = grid.Columns.OrderBy(c => c.DisplayIndex); 
    ICollectionView collectionView = CollectionViewSource.GetDefaultView(grid.ItemsSource); 
    foreach (object o in collectionView) 
    { 
     if (o.Equals(CollectionView.NewItemPlaceholder)) 
      continue; 

     foreach (DataGridColumn column in columns) 
     { 
      if (column is DataGridBoundColumn) 
      { 
       string propertyValue = string.Empty; 

       /* Get the property name from the column's binding */ 
       BindingBase bb = (column as DataGridBoundColumn).Binding; 
       if (bb != null) 
       { 
        Binding binding = bb as Binding; 
        if (binding != null) 
        { 
         string boundProperty = binding.Path.Path; 

         /* Get the property value using reflection */ 
         PropertyInfo pi = o.GetType().GetProperty(boundProperty); 
         if (pi != null) 
         { 
          object value = pi.GetValue(o); 
          if (value != null) 
           propertyValue = value.ToString(); 
         } 
        } 
       } 
       //... 
      } 
     } 
    } 
} 

S'il vous plaît se référer au blog suivant pour plus d'informations.

Comment exporter des données à partir d'un DataGrid WPF:https://blog.magnusmontin.net/2013/09/29/export-data-from-a-datagrid/