逐步解說:建立分類編輯器
WPF Designer for Visual Studio 的擴充性模型可讓您為屬性分類建立自訂編輯器,稱為分類編輯器。 分類編輯器可讓您提供自訂使用者介面。以便使用者編輯屬於單一分類的相關屬性,例如與文字相關的屬性。 在本逐步解說中,您將建置分類編輯器,以便使用者編輯控制項的文字相關屬性。
在這個逐步解說中,您會執行下列工作:
建立 WPF 自訂控制項專案。
建立分類編輯器,可用來編輯該控制項的文字相關屬性。
建立繼承自 CategoryEditor 的類別,以代表控制項的分類編輯器。
建立實作 IProvideAttributeTable 介面的類別,以註冊新的擴充編輯器。
在設計階段測試分類編輯器。
必要條件
您需要下列元件才能完成此逐步解說:
- Visual Studio 2010。
建立自訂控制項
第一個步驟是為自訂控制項建立專案。 這個控制項是一個具有少量設計階段程式碼的簡易按鈕,這個程式碼使用 GetIsInDesignMode 方法來實作設計階段行為。
建立自訂控制項
在 Visual C# 中建立名為 CustomControlLibrary 的新 WPF 自訂控制項程式庫。
CustomControl1 的程式碼隨即在 [程式碼編輯器] 中開啟。
在 CustomControl1 的 [程式碼編輯器] 中,將 CustomControlLibrary 命名空間 (Namespace) 中的程式碼替換成下列程式碼:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace CustomControlLibrary { public class CustomControl1 : Button { public CustomControl1() { if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) { Content = "In design mode"; } } } }
將專案的輸出路徑設定為 "bin\"。
建置方案。
建立類別來封裝屬性資訊
您將建立的分類編輯器需要一些字型和相關屬性的資訊,因此,您會建立類別來封裝這些資訊。 此類別將當做分類編輯器的資料來源。
若要建立封裝字型屬性資訊的類別
將 Visual C# 中名為 CustomControlLibrary.Design 的新 WPF 自訂控制項程式庫專案加入到方案中。
CustomControl1 的程式碼隨即在 [程式碼編輯器] 中開啟。
在 [方案總管] 中,從 CustomControlLibrary.Design 專案刪除 CustomControl1 檔案。
在 [方案總管] 中,從 CustomControlLibrary.Design 專案刪除 Themes 資料夾。
加入下列 WPF 設計工具組件的參考。
Microsoft.Windows.Design.Extensibility
Microsoft.Windows.Design.Interaction
加入 CustomControlLibrary 專案的參考。
將專案的輸出路徑設定為 ".. \CustomControlLibrary\bin\"。 這麼做會將控制項的組件和中繼資料組件保留在同一個資料夾中,讓設計工具可進行中繼資料探索。
將名為 FontList 的新類別加入到 CustomControlLibrary.Design 專案。
在 FontList 的 [程式碼編輯器] 中,以下列程式碼取代自動產生的程式碼。
using System; using System.Linq; using System.Collections.Generic; using System.Text; using System.Windows.Media; using System.Collections.ObjectModel; using System.Windows; using System.Windows.Data; using System.Globalization; namespace CustomControlLibrary.Design { public class FontList : ObservableCollection<FontFamily> { public FontList() { foreach (FontFamily ff in Fonts.SystemFontFamilies) { Add(ff); } } } public class FontSizeList : ObservableCollection<double> { public FontSizeList() { Add(8); Add(9); Add(10); Add(11); Add(12); Add(14); Add(16); Add(18); Add(20); } } public class FontStyleConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { FontStyle fs = (FontStyle)value; return fs == FontStyles.Italic; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (value != null) { bool isSet = (bool)value; if (isSet) { return FontStyles.Italic; } } return FontStyles.Normal; } } public class FontWeightConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { FontWeight fs = (FontWeight)value; return fs == FontWeights.Bold; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (value != null) { bool isSet = (bool)value; if (isSet) { return FontWeights.Bold; } } return FontWeights.Normal; } } }
建立分類編輯器的樣板
分類編輯器將使用 XAML 資料範本建立。 這會是繫結至數個文字相關屬性的簡單使用者介面。
若要建立分類編輯器的樣板
將名為 EditorResources 的新類別加入到 CustomControlLibrary.Design 專案。
在 EditorResources 的 [程式碼編輯器] 中,以下列程式碼取代自動產生的程式碼。
namespace CustomControlLibrary.Design { using System; using System.Collections.Generic; using System.Text; using System.Windows; public partial class EditorResources : ResourceDictionary { public EditorResources() : base() { InitializeComponent(); } } }
按一下 [專案] 功能表上的 [加入資源字典]。
將檔案命名為 EditorResources.xaml,然後按一下 [加入]。
在 EditorResources.xaml 的 [XAML] 檢視中,將自動產生的 XAML 替換成下列 XAML。
<ResourceDictionary xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:PropertyEditing="clr-namespace:Microsoft.Windows.Design.PropertyEditing;assembly=Microsoft.Windows.Design.Interaction" xmlns:Local="clr-namespace:CustomControlLibrary.Design" xmlns:Media="clr-namespace:System.Windows.Media;assembly=PresentationCore" xmlns:sys="clr-namespace:System;assembly=mscorlib" x:Class="CustomControlLibrary.Design.EditorResources"> <Local:FontList x:Key="FontFamilyList"/> <Local:FontSizeList x:Key="FontSizeList"/> <Local:FontStyleConverter x:Key="FontStyleConverter"/> <Local:FontWeightConverter x:Key="FontWeightConverter"/> <DataTemplate x:Key="TextCategoryEditorTemplate"> <StackPanel Margin="5"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="50"/> </Grid.ColumnDefinitions> <ComboBox Grid.Column="0" Margin="2" ItemsSource="{Binding Source={StaticResource FontFamilyList}}" SelectedItem="{Binding [FontFamily].PropertyValue.Value}"/> <ComboBox Grid.Column="1" Margin="2" ItemsSource="{Binding Source={StaticResource FontSizeList}}" SelectedItem="{Binding [FontSize].PropertyValue.Value}"/> </Grid> <StackPanel Orientation="Horizontal"> <CheckBox Margin="2" Content="Bold" IsChecked="{Binding Path=[FontWeight].PropertyValue.Value, Converter={StaticResource FontWeightConverter}}"/> <CheckBox Margin="2" Content="Italic" IsChecked="{Binding Path=[FontStyle].PropertyValue.Value, Converter={StaticResource FontStyleConverter}}"/> </StackPanel> </StackPanel> </DataTemplate> </ResourceDictionary>
建置方案。
封裝樣板和註冊分類編輯器
現在您已為分類編輯器建立了樣板,接下來就必須建立繼承自 CategoryEditor 的類別,以便使用樣板做為自訂編輯器,而且必須註冊新的分類編輯器。
若要封裝和註冊分類編輯器
將名為 TextCategoryEditor 的新類別加入到 CustomControlLibrary.Design 專案。
在 TextCategoryEditor 的 [程式碼編輯器] 中,以下列程式碼取代自動產生的程式碼。
namespace CustomControlLibrary.Design { using System; using System.Collections.Generic; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using Microsoft.Windows.Design.PropertyEditing; public class TextCategoryEditor : CategoryEditor { private EditorResources res = new EditorResources(); public TextCategoryEditor() { } public override bool ConsumesProperty(PropertyEntry property) { return true; } public override DataTemplate EditorTemplate { get { return res["TextCategoryEditorTemplate"] as DataTemplate; } } public override object GetImage(Size desiredSize) { return null; } public override string TargetCategory { get { return "Text"; } } } }
將名為 Metadata 的新類別加入到 CustomControlLibrary.Design 專案。
在 Metadata 的 [程式碼編輯器] 中,以下列程式碼取代自動產生的程式碼。
using System; using System.Collections.Generic; using System.Text; using Microsoft.Windows.Design.Metadata; using System.ComponentModel; using Microsoft.Windows.Design.PropertyEditing; using System.Windows.Media; using System.Windows.Controls; using System.Windows; using CustomControlLibrary; // The ProvideMetadata assembly-level attribute indicates to designers // that this assembly contains a class that provides an attribute table. [assembly: ProvideMetadata(typeof(CustomControlLibrary.Design.Metadata))] namespace CustomControlLibrary.Design { // Container for any general design-time metadata to initialize. // Designers look for a type in the design-time assembly that // implements IProvideAttributeTable. If found, designers instantiate // this class and access its AttributeTable property automatically. internal class Metadata : IProvideAttributeTable { // Accessed by the designer to register any design-time metadata. public AttributeTable AttributeTable { get { AttributeTableBuilder builder = new AttributeTableBuilder(); builder.AddCustomAttributes (typeof(CustomControl1), new EditorAttribute( typeof(TextCategoryEditor), typeof(TextCategoryEditor))); return builder.CreateTable(); } } } }
建置方案。
測試分類編輯器
分類編輯器現在已經完成並可以使用。 接著就要進行最後測試。 為測試分類編輯器,您會將 WPF 應用程式加入到專案、將自訂控制項加入到 WPF 應用程式,然後檢視分類編輯器的實際運作。
若要測試分類編輯器
將 Visual C# 中名為 DemoApplication 的新 WPF 應用程式專案加入至方案。
MainWindow.xaml 隨即在 WPF 設計工具中開啟。
加入 CustomControlLibrary 專案的參考。
在 MainWindow.xaml 的 XAML 檢視中,將自動產生的 XAML 替換為下列 XAML。 這個 XAML 會加入 CustomControlLibrary 命名空間的參考,並加入 CustomControl1 自訂控制項。 按鈕會顯示在 [設計] 檢視中,並顯示指出正處於設計模式的文字。 如果按鈕不顯示,您可能需要按一下設計工具頂端的資訊列以重新載入檢視。
<Window x:Class="DemoApplication.MainWindow" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300" xmlns:my="clr-namespace:CustomControlLibrary;assembly=CustomControlLibrary"> <Grid> <my:CustomControl1 Margin="30,30,30,30" Name="customControl11"></my:CustomControl1> </Grid> </Window>
在 [設計] 檢視中選取控制項。
在 [屬性] 視窗中,找到 [Text] 分類。
您應會看到指定 Text 屬性的使用者介面,這與其他控制項都不同。 您可以從下拉式清單選取字型名稱和字型大小。 您可以選取核取方塊來指定粗體和斜體。
變更出現在此分類中的屬性。 請注意,它們的變更會反映在控制項中。