I have a WPF program that produces several DataGrids. I have added capability to export each grid to Excel using the ideas at this site: http://www.codeproject.com/Articles/120480/Export-to-Excel-Functionality-in-WPF-DataGrid
Currently I just have a button under each grid that has its own handler that looks something like this:
private void m_btnExportTimePartitionToExcel_Click(object sender, RoutedEventArgs e)
{
try
{
ExportToExcel<SystemTimeRecordData, List<SystemTimeRecordData>> s = new ExportToExcel<SystemTimeRecordData, List<SystemTimeRecordData>>();
ICollectionView view = CollectionViewSource.GetDefaultView(m_gridPartitionSystemTimeRecords.ItemsSource);
s.dataToPrint = (List<SystemTimeRecordData>)view.SourceCollection;
s.GenerateReport();
}
catch (Exception ex)
{
MessageBox.Show("Problem with exporting Excel. Error: " + ex.Message);
}
}
I have a similar button handler for each grid. This all works, but it "smells". It seems there should be a way to have just one handler that each button calls. That is, if I can pass the grid associated with that button, and the relevant class. Can I do that from XAML? I have searched and seen examples of passing arguments, but not the grid itself and certainly not the class, which I'm guessing would have to be passed as a Type? It would be nice to replace the above code with something like...
private void m_btnExportTimePartitionToExcel_Click(object sender, RoutedEventArgs e)
{
try
{
// some how get Type type, and grid from sender and/or e
ExportToExcel<type, List<type>> s = new ExportToExcel<type, List<type>>();
ICollectionView view = CollectionViewSource.GetDefaultView(m_grid.ItemsSource);
s.dataToPrint = (List<type>)view.SourceCollection;
s.GenerateReport();
}
catch (Exception ex)
{
MessageBox.Show("Problem with exporting Excel. Error: " + ex.Message);
}
}
Then I could just have one button handler! Any ideas? Thanks, Dave
Here are a few ways you could do that:
You could try passing the DataGrid
as the CommandParameter
if you can find it using an ElementName
or RelativeSource
binding
<Button CommandParameter="{Binding ElementName=DataGridA}" ... /> <!-- Will only work if this is inside the DataGrid somewhere, like in the footer --> <Button CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}" ... />
You could then get the value with ((Button)sender).CommandParameter as DataGrid
You could pass the ItemsSource
as a CommandParameter
instead of the entire DataGrid
<StackPanel> <DataGrid ItemsSource="{Binding SomeCollection}" ... /> <Button CommandParameter="{Binding SomeCollection}" ... /> </StackPanel>
You could navigate the VisualTree to find the closest DataGrid. I have some helpers on my blog that make this easy. Here's an example using them with the above XAML:
var parentPanel = VisualTreeHelpers.FindAncestor<StackPanel>((Button)sender); var datagrid = VisualTreeHelpers.FindChild<DataGrid>(parentPanel);
I'm sure there's other ways too, but those are the first ones I thought of :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.