在 Visual Studio IDE 中,屬性視窗會依分類顯示屬性(如「Content」分類),這在 ASP.NET、WinForms 中透過 [Category] 屬性實現,WPF 自訂控件同樣適用:
public class DesginCustomControl : ContentControl {
[Category("Content")]
public string Content {
get { return (string)GetValue(ContentProperty); }
set { SetValue(ContentProperty, value); }
}
public static readonly DependencyProperty ContentProperty =
DependencyProperty.Register("Content", typeof(string), typeof(DesginCustomControl),
new UIPropertyMetadata(String.Empty));
}
效果即在屬性視窗的「Content」分類下顯示該屬性。
WPF 設計時允許將中繼資料與控件程式碼分離,採用獨立設計時組件:
WPF.ControlsWPF.Controls.VisualStudio.Design(命名慣例:控件組件名 + .VisualStudio.Design)bin 目錄),引用控件的專案無需額外引用設計時組件。Microsoft.Windows.Design 組件(WPF 設計時基礎庫)。public class WPFControlsCommonMetadata : IRegisterMetadata {
public void Register() {
AttributeTableBuilder builder = new AttributeTableBuilder();
builder.AddCustomAttributes(
typeof(DesginCustomControl),
DesginCustomControl.ContentProperty,
new Attribute[] { new CategoryAttribute("Content") });
MetadataStore.AddAttributeTable(builder.CreateTable());
}
}
AttributeTableBuilder 為屬性表建構器,MetadataStore 為中繼資料儲存區。此方式與直接在屬性上標註屬性效果相同,但優勢在於:可為無法繼承的內建控件(如 ASP.NET 內建控件)擴充設計時行為,無需建立衍生類別。
當控件數量龐大時,一次性載入所有中繼資料會影響效能。使用 AddCallback 可在需要時才註冊:
public class WPFControlsCommonMetadata : IRegisterMetadata {
public void Register() {
AttributeTableBuilder builder = new AttributeTableBuilder();
builder.AddCallback(typeof(DesginCustomControl), delegate(AttributeCallbackBuilder cb) {
cb.AddCustomAttributes(DesginCustomControl.ContentProperty,
new Attribute[] { new CategoryAttribute("Content") });
});
MetadataStore.AddAttributeTable(builder.CreateTable());
}
}
此機制確保只有當設計器實際載入該控件類型時,才會建立對應的中繼資料表。