更新 : 2007 年 11 月
カスタム機能コネクタを実装する方法を次のコード例に示します。詳細については、「チュートリアル : デザイン時装飾の作成」を参照してください。
使用例
FeatureConnector<FeatureProviderType> クラスから派生して、IDiagnosticsService という名前のカスタム サービスと DiagnosticsMenuProvider という名前のカスタム機能プロバイダを関連付ける方法を次のコード例に示します。
Imports System
Imports System.Windows
' The DemoButton control provides a button that
' has custom design-time behavior.
Public Class DemoButton
Inherits System.Windows.Controls.Button
End Class
using System;
using System.Windows;
namespace DemoControlLibrary
{
// The DemoButton control provides a button that
// has custom design-time behavior.
public class DemoButton : System.Windows.Controls.Button
{
}
}
Imports System
Imports Microsoft.Windows.Design.Features
Imports Microsoft.Windows.Design.Interaction
' The DiagnosticsMenuProvider class adds a context menu item
' that displays a dialog box listing the currently running and
' pending feature connectors.
<FeatureConnector(GetType(DiagnosticsFeatureConnector))> _
Public Class DiagnosticsMenuProvider
Inherits PrimarySelectionContextMenuProvider
Public Sub New()
Dim action As New MenuAction("Feature Diagnostics...")
AddHandler action.Execute, AddressOf action_Execute
Items.Add(action)
End Sub
Sub action_Execute(ByVal sender As Object, ByVal e As MenuActionEventArgs)
Dim service As IDiagnosticsService = e.Context.Services.GetRequiredService(Of IDiagnosticsService)()
service.ShowWindow()
End Sub
End Class
' The IDiagnosticsService specifies a simple interface for showing
' a FeatureManagerDiagnostics window.
Interface IDiagnosticsService
Sub ShowWindow()
End Interface
' The DiagnosticsFeatureConnector publishes the IDiagnosticsService.
Class DiagnosticsFeatureConnector
Inherits FeatureConnector(Of DiagnosticsMenuProvider)
Implements IDiagnosticsService
Dim fmdWindow As FeatureManagerDiagnostics
Public Sub New(ByVal manager As FeatureManager)
MyBase.New(manager)
Context.Services.Publish(Of IDiagnosticsService)(Me)
End Sub
' The showWindow method creates a FeatureManagerDiagnostics
' window and shows it.
Public Sub ShowWindow() Implements IDiagnosticsService.ShowWindow
If fmdWindow IsNot Nothing Then
' Show the FeatureManagerDiagnostics window.
fmdWindow.Show()
' Activate the
fmdWindow.Activate()
Else
fmdWindow = New FeatureManagerDiagnostics()
fmdWindow.Initialize(Manager)
AddHandler fmdWindow.Closed, AddressOf fmdWindow_Closed
fmdWindow.Show()
End If
End Sub
Sub fmdWindow_Closed(ByVal sender As Object, ByVal e As EventArgs)
fmdWindow = Nothing
End Sub
End Class
using System;
using Microsoft.Windows.Design.Features;
using Microsoft.Windows.Design.Interaction;
namespace DemoControlLibrary.VisualStudio.Design
{
// The DiagnosticsMenuProvider class adds a context menu item
// that displays a dialog box listing the currently running and
// pending feature connectors.
[FeatureConnector(typeof(DiagnosticsFeatureConnector))]
public class DiagnosticsMenuProvider : PrimarySelectionContextMenuProvider
{
public DiagnosticsMenuProvider()
{
MenuAction action = new MenuAction("Feature Diagnostics...");
action.Execute += new EventHandler<MenuActionEventArgs>(action_Execute);
Items.Add(action);
}
void action_Execute(object sender, MenuActionEventArgs e)
{
IDiagnosticsService service =
e.Context.Services.GetRequiredService<IDiagnosticsService>();
service.ShowWindow();
}
}
// The IDiagnosticsService specifies a simple interface for showing
// a FeatureManagerDiagnostics window.
interface IDiagnosticsService
{
void ShowWindow();
}
// The DiagnosticsFeatureConnector publishes the IDiagnosticsService.
class DiagnosticsFeatureConnector : FeatureConnector<DiagnosticsMenuProvider>,
IDiagnosticsService
{
FeatureManagerDiagnostics fmdWindow;
public DiagnosticsFeatureConnector(FeatureManager manager)
: base(manager)
{
Context.Services.Publish<IDiagnosticsService>(this);
}
#region IDiagnosticsService Members
// The showWindow method creates a FeatureManagerDiagnostics
// window and shows it.
public void ShowWindow()
{
if (fmdWindow != null)
{
fmdWindow.Show();
fmdWindow.Activate();
}
else
{
fmdWindow = new FeatureManagerDiagnostics();
fmdWindow.Initialize(Manager);
fmdWindow.Closed += new EventHandler(fmdWindow_Closed);
fmdWindow.Show();
}
}
void fmdWindow_Closed(object sender, EventArgs e)
{
fmdWindow = null;
}
#endregion
}
}
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Data
Imports System.Windows.Documents
Imports System.Windows.Input
Imports System.Windows.Media
Imports System.Windows.Media.Imaging
Imports System.Windows.Shapes
Imports Microsoft.Windows.Design.Features
' The FeatureManagerDiagnostics class implements a window
' that displays the running and pending feature connectors.
Partial Public Class FeatureManagerDiagnostics
Inherits Window
Private featManager As FeatureManager
Public Sub New()
InitializeComponent()
End Sub
Public Sub Initialize(ByVal manager As FeatureManager)
featManager = manager
Bind()
End Sub
Private Sub OnRefreshClick(ByVal sender As Object, ByVal e As RoutedEventArgs)
Bind()
End Sub
' Binds the activatedFeatures and pendingFeatures controls
' the FeatureManager's RunningConnectors and PendingConnectors\
' properties.
Private Sub Bind()
activatedFeatures.Items.Clear()
pendingFeatures.Items.Clear()
Dim info As FeatureConnectorInformation
For Each info In featManager.RunningConnectors
activatedFeatures.Items.Add(info)
Next info
For Each info In featManager.PendingConnectors
pendingFeatures.Items.Add(info)
Next info
End Sub
End Class
using System;
using System.Collections.Generic;
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.Shapes;
using Microsoft.Windows.Design.Features;
namespace DemoControlLibrary.VisualStudio.Design
{
// The FeatureManagerDiagnostics class implements a window
// that displays the running and pending feature connectors.
public partial class FeatureManagerDiagnostics : Window
{
private FeatureManager featManager;
public FeatureManagerDiagnostics()
{
InitializeComponent();
}
public void Initialize(FeatureManager manager)
{
featManager = manager;
Bind();
}
private void OnRefreshClick(object sender, RoutedEventArgs e)
{
Bind();
}
// Binds the activatedFeatures and pendingFeatures controls
// the FeatureManager's RunningConnectors and PendingConnectors\
// properties.
private void Bind()
{
activatedFeatures.Items.Clear();
pendingFeatures.Items.Clear();
foreach (FeatureConnectorInformation info in
featManager.RunningConnectors)
{
activatedFeatures.Items.Add(info);
}
foreach (FeatureConnectorInformation info in
featManager.PendingConnectors)
{
pendingFeatures.Items.Add(info);
}
}
}
}
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:DemoControlLibrary.VisualStudio.Design"
x:Class="FeatureManagerDiagnostics"
Title="Feature Diagnostics" WindowStartupLocation="CenterOwner" SizeToContent="Manual" Height="316" Width="448" >
<Window.Resources>
<Style x:Key="HeaderStyle" TargetType="HeaderedItemsControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="HeaderedItemsControl">
<StackPanel>
<Border Padding="5" Background="#FFDDDDDD">
<CheckBox IsChecked="True" FontWeight="Bold" Name="Expander" Content="{TemplateBinding Header}"/>
</Border>
<Border Padding="5" Name="ItemsHost">
<ItemsPresenter/>
</Border>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger SourceName="Expander" Property="ToggleButton.IsChecked" Value="true">
<Setter TargetName="ItemsHost" Property="Visibility" Value="Visible" />
</Trigger>
<Trigger SourceName="Expander" Property="ToggleButton.IsChecked" Value="false">
<Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="FeatureInfo" DataType="l:FeatureConnectorInformation">
<StackPanel>
<Border BorderBrush="{x:Static SystemColors.ActiveCaptionBrush}" BorderThickness="0,0,0,1">
<TextBlock FontWeight="Bold" Text="{Binding Path=FeatureConnectorType}" />
</Border>
<Border Padding="15,0,0,5" TextElement.FontSize = "10">
<StackPanel>
<TextBlock FontWeight="Bold" Text="Required Services" />
<Border Padding="10,0,0,5">
<ItemsControl ItemsSource="{Binding Path=RequiredServices}" />
</Border>
<TextBlock FontWeight="Bold" Text="Required Context Items" />
<Border Padding="10,0,0,5">
<ItemsControl ItemsSource="{Binding Path=RequiredItems}" />
</Border>
</StackPanel>
</Border>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="PendingFeatureInfo" DataType="l:FeatureConnectorInformation">
<StackPanel>
<Border BorderBrush="{x:Static SystemColors.ActiveCaptionBrush}" BorderThickness="0,0,0,1">
<TextBlock FontWeight="Bold" Text="{Binding Path=FeatureConnectorType}" />
</Border>
<Border Padding="15,0,0,5" TextElement.FontSize = "10">
<StackPanel>
<TextBlock FontWeight="Bold" Text="Missing Services" />
<Border Padding="10,0,0,5">
<ItemsControl ItemsSource="{Binding Path=PendingServices}" />
</Border>
<TextBlock FontWeight="Bold" Text="Missing Context Items" />
<Border Padding="10,0,0,5">
<ItemsControl ItemsSource="{Binding Path=PendingItems}" />
</Border>
</StackPanel>
</Border>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ScrollViewer Margin="0,0,0,36" VerticalScrollBarVisibility="Auto">
<StackPanel>
<HeaderedItemsControl Name="pendingFeatures" Style="{StaticResource HeaderStyle}" Header="Pending Features" ItemTemplate="{StaticResource PendingFeatureInfo}" />
<HeaderedItemsControl Name="activatedFeatures" Style="{StaticResource HeaderStyle}" Header="Activated Features" ItemTemplate="{StaticResource FeatureInfo}" />
</StackPanel>
</ScrollViewer>
<Button Height="23" Margin="0,0,8,7" Click="OnRefreshClick" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="75">Refresh</Button>
</Grid>
</Window>
<Window
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:DemoControlLibrary.VisualStudio.Design"
x:Class="DemoControlLibrary.VisualStudio.Design.FeatureManagerDiagnostics"
Title="Feature Diagnostics" WindowStartupLocation="CenterOwner" SizeToContent="Manual" Height="316" Width="448" >
<Window.Resources>
<Style x:Key="HeaderStyle" TargetType="HeaderedItemsControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="HeaderedItemsControl">
<StackPanel>
<Border Padding="5" Background="#FFDDDDDD">
<CheckBox IsChecked="True" FontWeight="Bold" Name="Expander" Content="{TemplateBinding Header}"/>
</Border>
<Border Padding="5" Name="ItemsHost">
<ItemsPresenter/>
</Border>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger SourceName="Expander" Property="ToggleButton.IsChecked" Value="true">
<Setter TargetName="ItemsHost" Property="Visibility" Value="Visible" />
</Trigger>
<Trigger SourceName="Expander" Property="ToggleButton.IsChecked" Value="false">
<Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="FeatureInfo" DataType="l:FeatureConnectorInformation">
<StackPanel>
<Border BorderBrush="{x:Static SystemColors.ActiveCaptionBrush}" BorderThickness="0,0,0,1">
<TextBlock FontWeight="Bold" Text="{Binding Path=FeatureConnectorType}" />
</Border>
<Border Padding="15,0,0,5" TextElement.FontSize = "10">
<StackPanel>
<TextBlock FontWeight="Bold" Text="Required Services" />
<Border Padding="10,0,0,5">
<ItemsControl ItemsSource="{Binding Path=RequiredServices}" />
</Border>
<TextBlock FontWeight="Bold" Text="Required Context Items" />
<Border Padding="10,0,0,5">
<ItemsControl ItemsSource="{Binding Path=RequiredItems}" />
</Border>
</StackPanel>
</Border>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="PendingFeatureInfo" DataType="l:FeatureConnectorInformation">
<StackPanel>
<Border BorderBrush="{x:Static SystemColors.ActiveCaptionBrush}" BorderThickness="0,0,0,1">
<TextBlock FontWeight="Bold" Text="{Binding Path=FeatureConnectorType}" />
</Border>
<Border Padding="15,0,0,5" TextElement.FontSize = "10">
<StackPanel>
<TextBlock FontWeight="Bold" Text="Missing Services" />
<Border Padding="10,0,0,5">
<ItemsControl ItemsSource="{Binding Path=PendingServices}" />
</Border>
<TextBlock FontWeight="Bold" Text="Missing Context Items" />
<Border Padding="10,0,0,5">
<ItemsControl ItemsSource="{Binding Path=PendingItems}" />
</Border>
</StackPanel>
</Border>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ScrollViewer Margin="0,0,0,36" VerticalScrollBarVisibility="Auto">
<StackPanel>
<HeaderedItemsControl Name="pendingFeatures" Style="{StaticResource HeaderStyle}" Header="Pending Features" ItemTemplate="{StaticResource PendingFeatureInfo}" />
<HeaderedItemsControl Name="activatedFeatures" Style="{StaticResource HeaderStyle}" Header="Activated Features" ItemTemplate="{StaticResource FeatureInfo}" />
</StackPanel>
</ScrollViewer>
<Button Height="23" Margin="0,0,8,7" Click="OnRefreshClick" VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="75">Refresh</Button>
</Grid>
</Window>
Imports System
Imports DemoControlLibrary
Imports Microsoft.Windows.Design.Metadata
Imports Microsoft.Windows.Design.Features
' Container for any general design-time metadata to initialize.
' Designers look for a type in the design-time assembly that
' implements IRegisterMetadata. If found, designers instantiate
' this class and call its Register() method automatically.
Friend Class Metadata
Implements IRegisterMetadata
Public Sub Register() Implements IRegisterMetadata.Register
Dim builder As New AttributeTableBuilder()
InitializeAttributes(builder)
MetadataStore.AddAttributeTable(builder.CreateTable())
End Sub
Private Sub InitializeAttributes(ByVal builder As AttributeTableBuilder)
builder.AddCallback(GetType(DemoButton), AddressOf AddButtonAttributes)
End Sub
Private Sub AddButtonAttributes(ByVal builder As AttributeCallbackBuilder)
builder.AddCustomAttributes(New FeatureAttribute(GetType(DiagnosticsMenuProvider)))
End Sub
End Class
' <//snippet101>
using System;
using DemoControlLibrary;
using Microsoft.Windows.Design.Metadata;
using Microsoft.Windows.Design.Features;
namespace DemoControlLibrary.VisualStudio.Design
{
// Container for any general design-time metadata to initialize.
// Designers look for a type in the design-time assembly that
// implements IRegisterMetadata. If found, designers instantiate
// this class and call its Register() method automatically.
internal class Metadata : IRegisterMetadata
{
public void Register()
{
AttributeTableBuilder builder = new AttributeTableBuilder();
InitializeAttributes(builder);
MetadataStore.AddAttributeTable(builder.CreateTable());
}
private void InitializeAttributes(AttributeTableBuilder builder)
{
builder.AddCallback(typeof(DemoButton), AddButtonAttributes);
}
private void AddButtonAttributes(AttributeCallbackBuilder builder)
{
builder.AddCustomAttributes(
new FeatureAttribute(typeof(DiagnosticsMenuProvider))
);
}
}
// <//snippet101>
}
<Window x:Class="Window1"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:DemoControlLibrary;assembly=DemoControlLibrary"
Title="Window1" Height="300" Width="300">
<Grid>
<c:DemoButton />
</Grid>
</Window>
<Window x:Class="DemoApplication.Window1"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:DemoControlLibrary;assembly=DemoControlLibrary"
Title="Window1" Height="300" Width="300">
<Grid>
<c:DemoButton />
</Grid>
</Window>
DemoButton クラスは Button クラスから派生し、デザイン時メタデータがアタッチされるクラスを提供します。
DiagnosticsMenuProvider クラスは、FeatureManagerDiagnostics ウィンドウを表示するコンテキスト メニュー項目を追加します。
FeatureManagerDiagnostics クラスは、実行中および保留中の機能コネクタを表示するウィンドウを実装します。
Metadata クラスは、MetadataStore クラスを使用して DiagnosticsMenuProvider を DemoButton にアタッチします。
コードのコンパイル方法
3 つのアセンブリで、前述のコード例をコンパイルします。
カスタム コントロールのコンパイル
Visual Studio で、DemoControlLibrary という名前の新しい WPF カスタム コントロール ライブラリ プロジェクトを作成します。
"CustomControl1" の出現箇所をすべて "DemoButton" に置き換えます。
DemoButton クラスの既存のコードを前に示したコードに置き換えます。
ソリューションをビルドします。
カスタム機能コネクタのコンパイル
DemoControlLibrary.VisualStudio.Design という名前の新しい WPF カスタム コントロール ライブラリ プロジェクトをソリューションに追加します。
プロジェクトの出力パスを "..\DemoControlLibrary\bin\Debug\" に設定します。
プロジェクトから Generic.xaml を削除します。
次のアセンブリへの参照を追加します。
Microsoft.Windows.Design
Microsoft.Windows.Design.Extensibility
Microsoft.Windows.Design.Interaction
DemoControlLibrary プロジェクトへの参照を追加します。
"CustomControl1" の出現箇所をすべて "DiagnosticsMenuProvider" に置き換えます。
DiagnosticsMenuProvider クラスの既存のコードを前に示したコードに置き換えます。
FeatureManagerDiagnostics という名前の Window (WPF) 項目をプロジェクトに追加します。
FeatureManagerDiagnostics クラスの既存のコードを前に示したコードに置き換えます。
FeatureManagerDiagnostics.xaml 内の既存の XAML を、前述した XAML に置き換えます。
Metadata という名前の新しいクラスをプロジェクトに追加します。
Metadata クラスの既存のコードを前に示したコードに置き換えます。
ソリューションをビルドします。
テスト アプリケーションのコンパイル
DemoApplication という名前の新しい WPF アプリケーション プロジェクトをソリューションに追加します。
DemoControlLibrary プロジェクトへの参照を追加します。
Window1.xaml 内の既存の XAML を、前述した XAML に置き換えます。
デザイン ビューで、ボタンを右クリックし、[Feature Diagnostics] をクリックします。
[Feature Diagnostics] ウィンドウが開き、保留中の機能コネクタとアクティブな機能コネクタが表示されます。
参照
処理手順
概念
参照
FeatureConnector<FeatureProviderType>