Выберите несколько ячеек в DataGrid и выведите на лист Excel - PullRequest
3 голосов
/ 05 апреля 2011

У меня есть DataGrid с сотнями строк и двумя столбцами данных.Мне нужно будет программно выбрать определенные строки и определенную ячейку в DataGrid и вывести их на лист Excel.После некоторых исследований кажется, что единственный способ получить значение ячейки - написать вспомогательную функцию, и вспомогательная функция запускается каждый раз, когда вы получаете ОДНО значение ячейки.получить значение определенной ячейки в DataGrid?Или я должен хранить каждое значение ячейки в массиве одновременно, когда оно идет в DataGrid, и выводить массив в Excel вместо DataGrid?

Ответы [ 2 ]

2 голосов
/ 06 апреля 2011

Допустим, что DataGrid отображает информацию о сотрудниках, для каждого сотрудника мы храним его Id, Name и Address. Позволяет добавить дополнительное логическое свойство для каждого свойства сотрудника (например, Id и IsIdSelected, Name и IsNameSelected), это логическое свойство будет связано со свойством 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", чтобы обеспечить программный выбор ячеек ( В этом случае вам нужно реализовать INotifyPropertyChanged для класса Employee).

С этим решением вам больше не нужны ни вспомогательная функция, ни доступ к фактическим ячейкам DataGrid, просто итерация по вашей коллекции, определение выбранных свойств и обработка их по мере необходимости.

0 голосов
/ 06 апреля 2011

В прошлом я использовал класс Clipboard, в котором вы можете получить значения, разделенные запятыми, из сетки, а затем сохранить их как CSV, а затем открыть их из Excel. Я думаю, это может зависеть от того, какой тип Grid Control вы используете

MSDN в буфере обмена

...