程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> wpf控件設計時支持(2)

wpf控件設計時支持(2)

編輯:關於.NET

這篇介紹在wpf設計時集合項屬性添加項的定義和自定義控件右鍵菜單的方法

集合項屬性設計時支持

1.為集合屬性設計器識別具體項類型

wpf設計器允許定義集合項的類型,如新發布的WPF的DataGrid控件,其中的Columns包括一下幾種類型,Columns集合屬性是以下幾個類型的抽象類集合.要在設計器識別以下類型,就必須用到wpf設計時的擴展功能

實現這個功能很簡單,只需要給該集合屬性附上NewItemTypesAttribute元數據就好了.如下代碼

NewItemTypesAttribute attr = new NewItemTypesAttribute(
                  typeof(DataGridTextColumn),
                  typeof(DataGridCheckBoxColumn),
                  typeof(DataGridHyperlinkColumn),
                  typeof(DataGridComboBoxColumn),
                  typeof(DataGridTemplateColumn));
builder.AddCustomAttributes("Columns", attr);

這裡通過把元數據添加到元數據存儲區的方式來實現,當然你也可以直接在屬性上掛元數據,兩種方法都可以,具體可以看第一篇的介紹.

2.格式化集合項屬性

如上圖,每個類型都配有不同的圖標,這一功能需要NewItemFactory 來完成,稱之為創建項的工廠,我理解為是格式化項.

NewItemFactory是一個抽象類,有三個虛方法

CreateInstance方法會在創建新實例時對該對象做一些業務邏輯的變更

GetDisplayName方法則獲取顯示的名稱,如下圖的DataGridTextColumn

GetImage方法則是獲取顯示的對象圖標了,如下圖左側圖標.

可以根據需要重寫這三個方法.我們來看下DataGridColumnFactory是如何實現的.

internal class DataGridColumnFactory : NewItemFactory
{
  public override object CreateInstance(Type type)
  {
    DataGridColumn gridColumn = null;
    if (type.IsAssignableFrom(typeof(DataGridTemplateColumn)))
    {
      gridColumn = CreateTemplateColumn();
    }
    else
    {
      gridColumn = Activator.CreateInstance(type) as DataGridColumn;
    }
    if (gridColumn != null)
    {
      gridColumn.Header = "Header";
    }
    return gridColumn;
  }
  /// <summary>
  ///   Create a Template column with a default cell and editing template
  /// </summary>
  private static DataGridTemplateColumn CreateTemplateColumn()
  {
    DataGridTemplateColumn gridColumn = new DataGridTemplateColumn();
    gridColumn.CellTemplate = new DataTemplate();
    gridColumn.CellEditingTemplate = new DataTemplate();
    return gridColumn;
  }
  public override object GetImage(Type type, Size desiredSize)
  {
    object image = base.GetImage(type, desiredSize);
    if (typeof(DataGridTextColumn).IsAssignableFrom(type))
    {
      image = Util.GetImage("DataGridTextColumn.png", desiredSize);
    }
    else if (typeof(DataGridHyperlinkColumn).IsAssignableFrom(type))
    {
      image = Util.GetImage("DataGridHyperlinkColumn.png", desiredSize);
    }
    else if (typeof(DataGridComboBoxColumn).IsAssignableFrom(type))
    {
      image = Util.GetImage("DataGridComboBoxColumn.png", desiredSize);
    }
    else if (typeof(DataGridCheckBoxColumn).IsAssignableFrom(type))
    {
      image = Util.GetImage("DataGridCheckBoxColumn.png", desiredSize);
    }
    else if (typeof(DataGridTemplateColumn).IsAssignableFrom(type))
    {
      image = Util.GetImage("DataGridTemplateColumn.png", desiredSize);
    }
    return image;
  }
}

以上代碼應該很容易理解.定義好這個工廠類以後則需要用NewItemTypesAttribute中的FactoryType屬性指定這個類型.現在剛開始的代碼變更如下

NewItemTypesAttribute attr = new NewItemTypesAttribute(
                  typeof(DataGridTextColumn),
                  typeof(DataGridCheckBoxColumn),
                  typeof(DataGridHyperlinkColumn),
                  typeof(DataGridComboBoxColumn),
                  typeof(DataGridTemplateColumn));
attr.FactoryType = typeof(DataGridColumnFactory);
builder.AddCustomAttributes("Columns", attr);

上下文菜單項

在我們使用wpf的datagird時候,在選中DataGrid控件時,點擊右鍵的話,會有一個自定義的DataGrid菜單,如下圖

wpf設計器允許對控件提供自定義菜單項,這是通過繼承一個名為PrimarySelectionContextMenuProvider的類實現的,上圖的右鍵菜單由DataGridMenuProvider來實現,我們來看一下具體實現方法.如下

1.聲明一個MenuGroup類,表明一個菜單項組,一個菜單則是一個MenuAction類.

通過MenuGroup的Items集合添加MenuAction.

2.更新菜單項狀態UpdateItemStatus ,該事件會都目前的菜單進行判斷,做出狀態變更,如初始化並未顯示Remove Columns這個菜單.

public DataGridMenuProvider()
{
  // Set up the MenuGroup which holds the MenuAction items.
  MenuGroup dataOperationsGroup = new MenuGroup("DataGroup", "DataGrid");
  isDatasourceSetMenuAction = new MenuAction("You need to set ItemsSource to enable some column operations.");
  generateStockColumnsMenuAction = new MenuAction("Generate Columns");
  generateStockColumnsMenuAction.Execute += new EventHandler<MenuActionEventArgs>(GenerateStockColumnsMenuAction_Execute);
  addColumnsMenuAction = new MenuAction("Add/Edit Columns...");
  addColumnsMenuAction.Execute += new EventHandler<MenuActionEventArgs>(AddColumnsMenuAction_Execute);
  removeColumnsMenuAction = new MenuAction("Remove Columns");
  removeColumnsMenuAction.Execute += new EventHandler<MenuActionEventArgs>(RemoveColumnsMenuAction_Execute);
  dataOperationsGroup.HasDropDown = true;
  dataOperationsGroup.Items.Add(isDatasourceSetMenuAction);
  dataOperationsGroup.Items.Add(generateStockColumnsMenuAction);
  dataOperationsGroup.Items.Add(addColumnsMenuAction);
  dataOperationsGroup.Items.Add(removeColumnsMenuAction);
  this.Items.Add(dataOperationsGroup);    // Can have groups - show up as sub menus
  
  // The UpdateItemStatus event is raised immediately before
  // the menu show, which provides the opportunity to set states.
  UpdateItemStatus += new EventHandler<MenuActionEventArgs>(DataGridMenuProvider_UpdateItemStatus);
}

MenuAction可以通過Execute事件觸發點擊事件.這就可以使得運行時控件與設計器之間進行交互,這裡涉及到一個wpf設計時的編輯模型放到下篇細講.這篇就介紹集合項屬性和自定義控件右鍵菜單的方法.下篇將會整理一個源碼一起放上.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved