2012-07-31 2 views
0

저는 WPF에 처음으로 익숙합니다. 동일한 유형의 모든 컨트롤에서 로직의 "factorisation"에 관한 질문이 있습니다.주어진 컨트롤 유형의 인스턴스에 대해 ContextMenu 만들기

정확하게 말하면, Infragistrics DataGrid의 모든 인스턴스에 대해, "그리드를 사용할 때마다 코드를 쓰지 않고"Excel로 내보내기 "버튼이있는 컨텍스트 메뉴를 갖고 싶습니다. 또한 기본적으로 항상 "Excel로 내보내기"상황에 맞는 메뉴 항목이있는 경우 항목별로 투명하게 항목을 추가 할 수 있기를 원합니다. 보너스는 특정 인스턴스에서 Excel로 내보내기 단추를 제거 할 수있는 것입니다.

  • DataGrid에 하위 클래스와 "OnInitialized"에 programmaticaly의 ContextMenu를 추가 :

    내 질문이 달성의 가장 좋은 방법은 무엇입니까? 문제 : 추가 메뉴 항목을 추가하고자하는 격자는 무엇입니까? XAML은 이미있는 항목을 무시합니다. 또한 내 컨트롤의 하위 클래스를 갖고 싶지 않고 직접 컨트롤 자체를 사용하고 WPF를 사용하여 의도 한 동작을 추가하는 것이 좋습니다.

  • "비헤이비어"사용? 이 유형의 그리드에 새로운 연결 속성을 추가 할 수는 있지만 좋은 연습인지 확실하지 않습니다.
  • 다른 건 없습니까?

제 질문이 의미가 되길 바랍니다.

참고 :이 질문은 Excel로 내보내기가 아니라 내 제어로이 작업을 수행하는 방법을 알고 있습니다.

답변

0

(ViewModel에서 바인딩하려는 경우 간단히 뒤에 코드에서 할당하고 간단한 CLR 속성을 만드는 경우) 컨트롤을 추가하고 menuItems의 목록에 바인딩하거나 할당합니다. 그리고 event DataGridLoaded 이벤트에서이 추가 menuItems을 Common MenuItem에 추가하십시오. 도움이 되었기를 바랍니다.

+0

답변 해 주셔서 감사합니다. 기존 컨트롤 (예 : 기존 "페이지"를 변경하고 싶지 않음)에 대해 가능한 한 덜 파괴적이기를 원하기 때문에 원하는 것은 아닙니다. 첨부 된 속성 솔루션을 사용하여 끝났습니다. 아래에서 내 솔루션을 게시합니다. –

0

결국 첨부 된 속성 솔루션을 사용했습니다. 그것은 매우 깨끗하고 기존 코드를 "오염"시키지 않습니다. 내보내기를 모든 데이터 그리드에 추가하려면 XAML 한 줄을 추가하면됩니다 (아래 참조).

<igDP:XamDataGrid 
        x:Name="summary" 
        Behaviours:XamDataGridBehaviours.ExportFileName="plop.xls" 
        ActiveDataItem="{Binding Path=SelectedSummary}"> 
[...] 
</igDP:XamDataGrid> 

첨부 된 등록 코드 자체

은 다음과 같습니다 : 당신이 볼 수 있듯이 우리는 그리드에 null 이외의 내보내기 파일 이름을 설정할 때마다

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로 끝나면 코드는 내보내기 항목이 있으면 제거하려고 시도합니다. 이렇게하면 xaml에 의해 설정된 다른 항목을 방지해서는 안되며 투명하게 유지해야합니다. 당신이 당신의 XAML에 그것을 할 경우

0

, 당신이 할 모시 :

<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> 

이 컨텍스트 메뉴에 새로운 객체를 추가 할 수 있습니다.

관련 문제