2011-04-05 55 views
3

我有一個包含數百行和兩列數據的DataGrid。我需要以編程方式選擇DataGrid中的某些行和某些特定單元格,並將它們輸出到Excel工作表上。 做了一些研究後,似乎獲得單元格值的唯一方法是編寫一個輔助函數,並且每次獲得ONE單元格值時都會運行輔助函數。在DataGrid中選擇多個單元並輸出到Excel工作表

是否有一種更容易/更快捷的方式來獲取DataGrid中特定單元格的值?或者我應該將每個單元格值存儲到一個數組並將其轉到DataGrid並將數組輸出到Excel而不是DataGrid?

回答

2

讓我們說什麼樣的網格控制的DataGrid顯示僱員的信息,對每個我們存儲了IdNameAddress員工。讓我們爲每個員工屬性添加一個額外的布爾屬性(例如IdIsIdSelected,NameIsNameSelected)此布爾屬性將綁定到DataGrid.IsSelected屬性,因此它表示是否選中該單元格,還可以使用它來選擇該單元格通過將其設置爲True以編程方式顯示指定的屬性。請看下面的代碼:

/// <summary> 
/// A class that represents an employee. Notice that with each property 
/// (e.g. Id) there is a Boolean property that has a similar name (e.g. IsIdSelected) 
/// this Boolean property will be bound to the relevant DataGridCell.IsSelected 
/// property to indicate whether the cell representing this property were selected 
/// or not. In other words if you want to know the selected properties at any moment 
/// you just need to iterate through the employees collection, and examine each 
/// Boolean property for each property :D 
/// </summary> 
public class Employee 
{ 
    public int? Id { get; set; } 
    public bool IsIdSelected { get; set; } 

    public string Name { get; set; } 
    public bool IsNameSelected { get; set; } 

    public string Address { get; set; } 
    public bool IsAddressSelected { get; set; } 
} 

後面的代碼:

using System.Collections.ObjectModel; 
using System.Windows; 

namespace CellSelection 
{ 
    public partial class MainWindow : Window 
    { 
     /// <summary> 
     /// The DataGrid will be bound to this collection 
     /// </summary> 
     private ObservableCollection<Employee> _collection; 

     public MainWindow() 
     { 
      InitializeComponent(); 

      // Initialize the employees collection with some test data 
      _collection = 
       new ObservableCollection<Employee> 
        { 
         new Employee {Id = 1, Name = "Mohammed A. Fadil", Address = "..."}, 
         new Employee {Id = 485, Name = "Khalid Zein", Address = "..."}, 
         new Employee {Id = 64, Name = "Ahmed Mubarak", Address = "..."}, 
         new Employee {Id = 364, Name = "Ali Ebraheim", Address = "..."}, 
        }; 

      DataContext = _collection; 
     } 

     private void OnExportButtonClick(object sender, RoutedEventArgs e) 
     { 
      // Now, concatinate all the selected cells 
      var str = string.Empty; 
      foreach (var emp in _collection) 
      { 
       if (emp.IsIdSelected) 
        str += string.Format("{0}, ", emp.Id); 

       if (emp.IsNameSelected) 
        str += string.Format("{0}, ", emp.Name); 

       if (emp.IsAddressSelected) 
        str += string.Format("{0}", emp.Address); 

       str += "\n"; 
      } 
      // Instead of displaying this message you could export these cells to Excel 
      // in the format you need. 
      MessageBox.Show(str); 
     } 
    } 
} 

的XAML代碼:

<Window x:Class="CellSelection.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"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="275*" /> 
      <RowDefinition Height="36*" /> 
     </Grid.RowDefinitions> 
     <DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False" 
        SelectionMode="Extended" SelectionUnit="CellOrRowHeader"> 
      <DataGrid.Columns> 

       <DataGridTextColumn Header="Id" Binding="{Binding Id}"> 
        <DataGridTextColumn.CellStyle> 
         <Style TargetType="DataGridCell"> 
          <Setter Property="IsSelected"> 
           <Setter.Value> 
            <Binding Path="IsIdSelected" Mode="TwoWay" 
              UpdateSourceTrigger="PropertyChanged"/> 
           </Setter.Value> 
          </Setter> 
         </Style> 
        </DataGridTextColumn.CellStyle> 
       </DataGridTextColumn> 

       <DataGridTextColumn Header="Name" Binding="{Binding Name}"> 
        <DataGridTextColumn.CellStyle> 
         <Style TargetType="DataGridCell"> 
          <Setter Property="IsSelected"> 
           <Setter.Value> 
            <Binding Path="IsNameSelected" Mode="TwoWay" 
              UpdateSourceTrigger="PropertyChanged"/> 
           </Setter.Value> 
          </Setter> 
         </Style> 
        </DataGridTextColumn.CellStyle> 
       </DataGridTextColumn> 

       <DataGridTextColumn Header="Address" Binding="{Binding Address}"> 
        <DataGridTextColumn.CellStyle> 
         <Style TargetType="DataGridCell"> 
          <Setter Property="IsSelected"> 
           <Setter.Value> 
            <Binding Path="IsAddressSelected" Mode="TwoWay" 
              UpdateSourceTrigger="PropertyChanged"/> 
           </Setter.Value> 
          </Setter> 
         </Style> 
        </DataGridTextColumn.CellStyle> 
       </DataGridTextColumn> 
      </DataGrid.Columns> 
     </DataGrid> 
     <Button Content="Export Selection" Grid.Row="1" HorizontalAlignment="Right" 
       Click="OnExportButtonClick" Margin="5"/> 
    </Grid> 
</Window> 

請注意,每個DataGrid列,你必須增加一個CellStyle結合每一列指定布爾屬性爲DataGridCell.IsSelected屬性,將此綁定模式設置爲Mode="TwoWay"以便支持選擇單元格以編程方式(在這種情況下,您必須在Employee課上實施INotifyPropertyChanged)。

使用此解決方案,您不需要幫助器功能,也不需要訪問DataGrid實際單元格,只需遍歷集合,確定所選屬性並根據需要處理它們即可。

0

我過去曾使用剪貼板類,您可以從網格中獲取逗號分隔值,然後將其保存爲CSV,然後從Excel中打開它。我想這可能取決於你使用

MSDN On Clipboard

相關問題