简体   繁体   中英

Sending Grid name and class name from XAML button press in WPF

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM