我最終使用了附加的屬性解決方案。它非常乾淨,不會「污染」現有的代碼。您只需添加一行XAML(見下文),即可將導出添加到任何數據網格的excel功能。
<igDP:XamDataGrid
x:Name="summary"
Behaviours:XamDataGridBehaviours.ExportFileName="plop.xls"
ActiveDataItem="{Binding Path=SelectedSummary}">
[...]
</igDP:XamDataGrid>
附加屬性代碼本身低於:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using Infragistics.Documents.Excel;
using Infragistics.Windows.DataPresenter;
using Infragistics.Windows.DataPresenter.ExcelExporter;
using Microsoft.Win32;
namespace MYCOMPANY.Plugin.Framework.Behaviours
{
public class XamDataGridBehaviours
{
public static readonly DependencyProperty ExportFileNameProperty = DependencyProperty.RegisterAttached(
"ExportFileName",
typeof(string),
typeof(XamDataGridBehaviours),
new FrameworkPropertyMetadata(OnExportCommandChanged));
private const string ExportToExcelHeader = "Export to Excel";
[AttachedPropertyBrowsableForType(typeof(XamDataGrid))]
public static string GetExportFileName(XamDataGrid d)
{
return (string)d.GetValue(ExportFileNameProperty);
}
public static void SetExportFileName(XamDataGrid d, string value)
{
d.SetValue(ExportFileNameProperty, value);
}
static void OnExportCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var grid = d as XamDataGrid;
var fileName = (string) e.NewValue;
if (grid != null && !string.IsNullOrEmpty(fileName))
{
CreateExcelExportMenu(grid, fileName);
}
else if (grid != null && grid.ContextMenu != null)
{
SafeDeleteMenuItem(grid.ContextMenu);
}
}
private static void CreateExcelExportMenu(XamDataGrid grid, string fileName)
{
var contextMenu = grid.ContextMenu ?? new ContextMenu();
var exportToExcel = GetOrCreateMenuItem(grid, contextMenu, fileName);
contextMenu.Items.Add(exportToExcel);
grid.ContextMenu = contextMenu;
}
private static void ExportToExcel(XamDataGrid grid, string fileName)
{
var saveFileDialog = new SaveFileDialog();
saveFileDialog.FileName = fileName;
saveFileDialog.DefaultExt = ".xls";
saveFileDialog.Filter = "Excel spreadsheets (.xls)|*.xls";
if (saveFileDialog.ShowDialog() == true)
{
var exporter = new DataPresenterExcelExporter();
exporter.Export(grid, saveFileDialog.FileName, WorkbookFormat.Excel97To2003);
}
}
private static MenuItem GetOrCreateMenuItem(XamDataGrid grid, ContextMenu menu, string fileName)
{
foreach (var item in menu.Items)
{
if (item is MenuItem)
{
var menuitem = item as MenuItem;
if (menuitem.Header.ToString() == ExportToExcelHeader)
{
menuitem.Command = new RelayCommand(o => ExportToExcel(grid, fileName));
return menuitem;
}
}
}
var exportToExcel = new MenuItem();
exportToExcel.Header = ExportToExcelHeader;
exportToExcel.Command = new RelayCommand(o => ExportToExcel(grid, fileName));
var icon = new Image();
var bmImage = new BitmapImage();
bmImage.BeginInit();
bmImage.UriSource = new Uri(@"..\..\Images\excel.png", UriKind.RelativeOrAbsolute);
bmImage.EndInit();
icon.Source = bmImage;
icon.MaxWidth = 16;
exportToExcel.Icon = icon;
return exportToExcel;
}
private static void SafeDeleteMenuItem(ContextMenu menu)
{
MenuItem toDelete = null;
foreach (var item in menu.Items)
{
if (item is MenuItem)
{
var menuitem = item as MenuItem;
if (menuitem.Header.ToString() == ExportToExcelHeader)
{
toDelete = menuitem;
break;
}
}
}
if (toDelete != null)
menu.Items.Remove(toDelete);
}
}
}
正如你可以看到,當我們設置一個非空的導出文件名到網格,該代碼將一個導出到Excel項目。如果文件名最終爲空,則代碼將嘗試刪除導出項目(如果存在)。這樣,它不應該阻止其他項目由XAML設置,並應保持透明。
感謝您的回答!儘管我想盡可能減少對現有控制的干擾(即我不想改變現有的「頁面」),但這並不是我想要的。我最終使用了附加的屬性解決方案,我將在下面發佈我的解決方案。 – 2012-07-31 09:14:06