0

私はWPFにかなり慣れていないので、同じタイプのすべてのコントロールにわたるロジックの「因数分解」について質問があります。

より正確に言うと、Infragistics DataGrid の任意のインスタンスに対して、グリッドを使用するたびにコードを記述することなく、[Excel にエクスポート] ボタンを含むコンテキスト メニューが必要です。また、デフォルトで「Excel にエクスポート」コンテキスト メニュー項目が常にある場合は、ケースバイケースで透過的に項目を追加できるようにしたいと考えています。おまけとして、特定のインスタンスで [Excel にエクスポート] ボタンを削除できます。

私の質問は、これを達成するための最良の方法は何ですか:

  • DataGrid をサブクラス化し、「OnInitialized」にプログラムで ContextMenu を追加しますか? 問題: 追加のメニュー項目を追加したいグリッドはどうですか? XAML は既存のものを上書きしますか? また、コントロールのサブクラスを持たないことを好みます。コントロール自体を直接使用し、WPF を使用して意図した動作を追加します。
  • 「振る舞い」を使用していますか?このタイプのグリッドに新しい添付プロパティを追加できますが、それが良い方法かどうかはわかりません
  • 他に何か?

私の質問が理にかなっていることを願っています!

注: この質問は Excel へのエクスポートに関するものではありません。自分のコントロールでこれを行う方法を知っています。

4

3 に答える 3

0

XAML で行う場合は、次のことができます。

<DataGrid>
  <DataGrid.ContextMenu>
     <!--Binding to your view model and the command is whatever your command name should be ->
     <MenuItem Header="Export to CSV" Command="{Binding Export}"/>
  </DataGrid.ContextMenu>
</DataGrid>

これにより、新しいオブジェクトをコンテキスト メニューに追加できます。

于 2012-07-31T11:04:51.087 に答える
0

List<MenuItem> DependencyProperty(からバインドするViewModel場合。単純にコード ビハインドから割り当てたい場合は、単純な CLR プロパティを作成します) をデータグリッド コントロールに作成し、それを追加のリストにバインド/割り当てますmenuItems。イベントでは、event DataGridLoadedこれらの追加menuItems機能を Common MenuItems に追加します。これが役立つことを願っています。

于 2012-07-31T08:39:42.227 に答える
0

最終的には、添付プロパティ ソリューションを使用しました。非常にクリーンで、既存のコードを「汚染」しません。XAML を 1 行追加するだけで (以下を参照)、export to 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);
        }
    }
}

ご覧のとおり、null 以外のエクスポート ファイル名をグリッドに設定すると、コードは Excel アイテムへのエクスポートを追加します。ファイル名が null になった場合、コードはエクスポート項目が存在する場合はそれを削除しようとします。このようにして、xaml によって他の項目が設定されるのを妨げず、透過性を維持する必要があります。

于 2012-07-31T09:23:27.040 に答える