WPF DataGrid转csv,只导出网格中可见的值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34704314/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 13:37:01  来源:igfitidea点击:

WPF DataGrid to csv, exporting only the visible values in the grid

c#wpfxamlcsvdatagrid

提问by Sjokoladefoged

I'm fairly new to WPF and was wondering whether a possibility exists to simply export a WPF DataGrid to a csv file. I've tried using reflections to get the values needed, though that works to some extent I was wondering whether it's possible with an attached property to get the displayed values, these do not necessarily correspond to the values of the item source. The below attached property works as long as I use a static string, or a static resource of a string etc. If I try to use the columns bindings I just get a the default string.empty

我对 WPF 还很陌生,想知道是否有可能将 WPF DataGrid 简单地导出到 csv 文件。我尝试使用反射来获取所需的值,尽管这在某种程度上有效,但我想知道是否可以使用附加属性来获取显示的值,这些值不一定对应于项目源的值。只要我使用静态字符串或字符串的静态资源等,下面的附加属性就可以工作。如果我尝试使用列绑定,我只会得到一个默认的 string.empty

    public static readonly DependencyProperty ExportStringProperty =
        DependencyProperty.RegisterAttached("ExportString", //name of    attached property
        typeof(string), //type of attached property
        typeof(ExportBehaviour), //type of this owner class
        new PropertyMetadata(string.Empty)); //the default value of the attached property

    public static string GetExportString(DataGridColumn column)
    {
        return (string)column.GetValue(ExportStringProperty);
    }

    public static void SetExportString(DataGridColumn column, string value)
    {
        column.SetValue(ExportStringProperty, value);
    }

Is there a similar way to get the binding value from xaml in a way like:

是否有类似的方法可以通过以下方式从 xaml 获取绑定值:

    <DataGridTextColumn Header="Name" Binding="{Binding (datagridexcel:Product.Name)}" datagridexcel:ExportBehaviour.ExportString="{Binding (datagridexcel:Product.Name)}"/>

as said, the above earlier works for a static typed string and not for the binding. It has to be said that working with the item source in this case should be avoided and the only thing I'm interested in is the datagrid and the values shown there.

如上所述,以上早先适用于静态类型字符串,而不适用于绑定。必须说在这种情况下应该避免使用项目源,我唯一感兴趣的是数据网格和那里显示的值。

回答by Szabolcs Dézsi

I made this simple app to demonstrate a way of getting CSV from DataGrid. You have the DataGrid:

我制作了这个简单的应用程序来演示一种从DataGrid. 你有DataGrid

<DataGrid x:Name="MyDataGrid" Grid.Row="0" ItemsSource="{Binding Rows}" />

In this example it's bound to the following property in the viewmodel:

在此示例中,它绑定到视图模型中的以下属性:

private IEnumerable<RowViewModel> _rows;
public IEnumerable<RowViewModel> Rows
{
    get { return _rows; }
    set
    {
        _rows = value;
        OnPropertyChanged("Rows");
    }
}

Rows are set to the following sample data:

行设置为以下示例数据:

Rows = new List<RowViewModel>
{
    new RowViewModel { FirstName = "John", LastName = "Doe", DateOfBirth = new DateTime(1988, 12, 19) },
    new RowViewModel { FirstName = "Lara", LastName = "Croft", DateOfBirth = new DateTime(1975, 5, 3) },
    new RowViewModel { FirstName = "Sam", LastName = "Fisher", DateOfBirth = new DateTime(1967, 2, 9) }
};

Under the DataGridI have a Button:

根据DataGrid我有一个Button

<Button Grid.Row="1" Content="Copy values as CSV" Command="{Binding CopyAsCsvCommand}" CommandParameter="{Binding ElementName=MyDataGrid}" />

It's bound to a Commandin the viewmodel and the CommandParameteris the whole DataGrid.

它绑定到Command视图模型中的 a 并且CommandParameter是整个DataGrid.

CopyAsCsvCommand = new DelegateCommand<DataGrid>(CopyAsCsvHandler);

The Command's handler method where the actual copying happens:

Command的处理方法,其中实际发生的复制:

private void CopyAsCsvHandler(DataGrid dg)
{
    dg.SelectAllCells();
    dg.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
    ApplicationCommands.Copy.Execute(null, dg);
    dg.UnselectAllCells();
    LivePreviewText = (string)Clipboard.GetData(DataFormats.CommaSeparatedValue);
}

This is equivalent to selecting all the cells with CTRL+A and pressing CTRL+C.

这等效于使用 CTRL+A 选择所有单元格并按 CTRL+C。

Example

例子

Example image

示例图像

Now that you have the CSV content you can just save it down to a file with CSV extension. I hope this helps and this is what you were looking for.

现在您有了 CSV 内容,您可以将其保存到一个带有 CSV 扩展名的文件中。我希望这会有所帮助,这就是您要寻找的。

回答by Kavinda Gehan

This worked for me. Datagrid Export to CSV (WPF)

这对我有用。数据网格导出到 CSV (WPF)

   private void button_Click(object sender, RoutedEventArgs e)
    {       
        dataGrid1.SelectAllCells();
        dataGrid1.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
        ApplicationCommands.Copy.Execute(null, dataGrid1);
        dataGrid1.UnselectAllCells();
        String result = (string)Clipboard.GetData(DataFormats.CommaSeparatedValue);
        File.AppendAllText("D:\test.csv", result, UnicodeEncoding.UTF8);

    }