次の方法で共有


チュートリアル : カテゴリ エディタの作成

更新 : 2007 年 11 月

Windows Presentation Foundation (WPF) Designer for Visual Studio の機能拡張モデルを使用すると、カテゴリ エディタという、プロパティのカテゴリ用のカスタム エディタを作成できます。カテゴリ エディタを使用すると、テキスト関連プロパティなど、1 つのカテゴリに属する互いに関連するプロパティを編集するためのカスタム ユーザー インターフェイスを提供できます。このチュートリアルでは、コントロールのテキスト関連プロパティを編集するためのカテゴリ エディタを作成します。

このチュートリアルでは次のタスクを行います。

  • WPF カスタム コントロール プロジェクトを作成する。

  • そのコントロールのテキスト関連プロパティを編集するために使用されるカテゴリ エディタを作成する。

  • コントロールのカテゴリ エディタを表す CategoryEditor から継承するクラスを作成する。

  • 新しい拡張エディタを登録するために IRegisterMetadata 派生クラスを作成する。

  • デザイン時にカテゴリ エディタをテストする。

前提条件

このチュートリアルを完了するには、次のコンポーネントが必要です。

  • Visual Studio 2008。

カスタム コントロールの作成

最初に、カスタム コントロールのプロジェクトを作成します。コントロールは、デザイン時コードが少量のシンプルなボタンにします。このボタンは、GetIsInDesignMode メソッドを使用して、デザイン時動作を実装します。

カスタム コントロールを作成するには

  1. Visual C# で CustomControlLibrary という名前の新しい WPF カスタム コントロール ライブラリ プロジェクトを作成します。

    コード エディタで CustomControl1 のコードが開きます。

  2. 次の WPF デザイナ アセンブリへの参照を追加します。

    • Microsoft.Windows.Design
  3. CustomControl1 のコード エディタで、CustomControlLibrary 名前空間のコードを次のコードに置き換えます。

    public class CustomControl1 : Button
    {
        public CustomControl1()
        {
            if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
            {
                Content = "I'm in design mode";
            }
        }
    }
    
  4. プロジェクトの出力パスを "bin\" に設定します。

  5. ソリューションをビルドします。

プロパティ情報をカプセル化するクラスの作成

作成されるカテゴリ エディタは、フォントおよび関連するプロパティについての情報を必要とするため、それらの情報をカプセル化するクラスをここで作成します。このクラスは、カテゴリ エディタによってデータ ソースとして使われます。

フォント プロパティ情報をカプセル化するクラスを作成するには

  1. Visual C# で CustomControlLibrary.Design という名前の新しい WPF カスタム コントロール ライブラリ プロジェクトをソリューションに追加します。

    コード エディタで CustomControl1 のコードが開きます。

  2. ソリューション エクスプローラで、CustomControl1 ファイルを CustomControlLibrary.Design プロジェクトから削除します。

  3. ソリューション エクスプローラで、Themes フォルダを CustomControlLibrary.Design プロジェクトから削除します。

  4. 次の WPF デザイナ アセンブリへの参照を追加します。

    • Microsoft.Windows.Design
  5. CustomControlLibrary プロジェクトへの参照を追加します。

  6. プロジェクトの出力パスを "..\CustomControlLibrary\bin\" に設定します。これにより、コントロールのアセンブリとメタデータのアセンブリが同じフォルダ内に配置されるため、デザイナがメタデータを検出できます。

  7. FontList という名前の新しいクラスを CustomControlLibrary.Design プロジェクトに追加します。

  8. 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 データ テンプレートを使用して作成されます。これは、いくつかのテキスト関連プロパティにバインドされる簡単なユーザー インターフェイスです。

カテゴリ エディタのテンプレートを作成するには

  1. EditorResources という名前の新しいクラスを CustomControlLibrary.Design プロジェクトに追加します。

  2. 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();
            }
        }
    }
    
  3. [プロジェクト] メニューの [リソース ディクショナリの追加] をクリックします。

  4. フォームに EditorResources.xaml という名前を付け、[追加] をクリックします。

  5. EditorResources の 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"
        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}}" 
                        DisplayMemberPath="FamilyNames.Values[0]"
                        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>
    
  6. ソリューションをビルドします。

テンプレートのカプセル化とカテゴリ エディタの登録

カテゴリ エディタ用のテンプレートを作成した後は、このテンプレートをカスタム エディタとして使用するために CategoryEditor 派生クラスを作成し、新しいカテゴリ エディタを登録する必要があります。

カテゴリ エディタをカプセル化および登録するには

  1. TextCategoryEditor という名前の新しいクラスを CustomControlLibrary.Design プロジェクトに追加します。

  2. 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"; }
            }
        }
    }
    
  3. Metadata という名前の新しいクラスを CustomControlLibrary.Design プロジェクトに追加します。

  4. Metadata のコード エディタで、自動的に生成されたコードを次のコードに置き換えます。

    namespace CustomControlLibrary.Design
    {
        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;
    
        // Container for any general design-time metadata that we want to initialize.
        // Designers will look for a type in the design-time assembly that implements IRegisterMetadata.
        // If found, they will instantiate it and call its Register() method automatically.
        internal class Metadata : IRegisterMetadata
        {
    
            // Called by the WPF Designer to register any design-time metadata
            public void Register()
            {
                AttributeTableBuilder builder = new AttributeTableBuilder();
                builder.AddCustomAttributes
                    (typeof( CustomControl1), 
                    "Enter text",
                    PropertyValueEditor.CreateEditorAttribute(
                        typeof(TextCategoryEditor)));
                MetadataStore.AddAttributeTable(builder.CreateTable());
            }
        }
    }
    
  5. ソリューションをビルドします。

カテゴリ エディタのテスト

これでカテゴリ エディタが完成し、使用できる状態になりました。後はテストするだけです。カテゴリ エディタをテストするには、WPF アプリケーションをプロジェクトに追加し、カスタム コントロールを WPF アプリケーションに追加して、カテゴリ エディタの動作を確認します。

カテゴリ エディタをテストするには

  1. Visual C# の DemoApplication という名前の WPF アプリケーション プロジェクトをソリューションに追加します。

    WPF デザイナで Window1.xaml が開きます。

  2. CustomControlLibrary プロジェクトへの参照を追加します。

  3. Window1.xaml の XAML ビューで、自動的に生成された XAML を次の XAML に置き換えます。この XAML により、CustomControlLibrary 名前空間への参照が追加され、CustomControl1 カスタム コントロールが追加されます。現在デザイン モードであることを示すテキストと共に、ボタンがデザイン ビューに表示されます。ボタンが表示されない場合は、デザイナの一番上の情報バーをクリックして、ビューの再読み込みを行う必要があります。

    <Window x:Class="DemoApplication.Window1"
        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>
    
  4. デザイン ビューでコントロールを選択します。

  5. [プロパティ] ウィンドウで、テキスト カテゴリを見つけます。

    他のコントロールとは異なる、テキスト プロパティを指定するユーザー インターフェイスが表示されていることを確認してください。フォント名とフォント サイズをドロップダウン リストから選択できます。チェック ボックスをオンにすると、太字と斜体を指定できます。

  6. このカテゴリに含まれるプロパティを変更します。変更内容がコントロールに反映されます。

参照

処理手順

チュートリアル : カラー エディタの実装

方法 : 値エディタを作成する

その他の技術情報

カスタム エディタの作成

WPF デザイナの機能拡張