Поделиться через


Пошаговое руководство. Создание редактора категорий

Модель расширения среды для Конструктор WPF для Visual Studio позволяет создавать пользовательские редакторы для категорий свойств, известные как редакторы категорий. Редакторы категорий позволяют предоставить настраиваемый интерфейс пользователя, посредством которого пользователи смогут редактировать свойства из одной категории, например свойства, имеющие отношение к тексту. В этом пошаговом руководстве будет построен редактор категорий, позволяющий пользователям редактировать свойства элемента управления, связанные с текстом.

В данном пошаговом руководстве выполняются следующие задачи.

  • Создание проекта пользовательского элемента управления WPF.

  • Создание редактора категорий, который может быть использован для редактирования свойств элемента управления, связанных с текстом.

  • Создание класса, производного от класса CategoryEditor, который представляет редактор категорий для элемента управления.

  • Создайте класс, реализующий интерфейс IProvideAttributeTable, для регистрации нового расширенного редактора.

  • Тестирование редактора категорий во время разработки.

Обязательные компоненты

Ниже приведены компоненты, необходимые для выполнения данного пошагового руководства.

  • Visual Studio 2010.

Создание пользовательского элемента управления

Первым этапом является создание проекта для пользовательского элемента управления. Этот элемент управления представляет собой простую кнопку, созданную с помощью небольшого количества кода, в котором для реализации поведения во время разработки используется метод GetIsInDesignMode.

Создание пользовательского элемента управления

  1. Создайте новый проект библиотеки настраиваемых элементов управления WPF на языке Visual C# с именем CustomControlLibrary.

    В редакторе кода откроется код для элемента управления CustomControl1.

  2. В редакторе кода для CustomControl1 замените код в пространстве имен CustomControlLibrary следующим кодом:

    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";
                }
            }
        }
    }
    
  3. Задайте выходной путь проекта как "bin\".

  4. Выполните построение решения.

Создание класса для включения сведений о свойстве

Для создаваемого редактора категорий требуется некоторая информация о шрифтах и соответствующих свойствах, поэтому следует создать класс, содержащий эту информацию. Этот класс будет использоваться редактором категорий в качестве источника данных.

Создание класса для включения информации о шрифтах

  1. Добавьте к решению новый проект библиотеки пользовательских элементов управления WPF в Visual C# с именем CustomControlLibrary.Design.

    Код для CustomControl1 откроется в редакторе кода.

  2. В обозревателе решений удалите файл CustomControl1 из проекта CustomControlLibrary.Design.

  3. В обозревателе решений удалите папку "Themes" из проекта CustomControlLibrary.Design.

  4. Добавьте ссылку на следующие сборки сред. Конструктор WPF.

    • Microsoft.Windows.Design.Extensibility

    • Microsoft.Windows.Design.Interaction

  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. В представлении XAML для класса "EditorResources" замените автоматически создаваемый код на следующий код.

        <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>
    
  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 замените автоматически создаваемый код на следующий код.

    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();
                }
            }
        }
    }
    
  5. Выполните построение решения.

Тестирование редактора категорий

Теперь редактор категорий готов к использованию. Остается только протестировать его. Чтобы протестировать редактор категорий, добавьте приложение WPF к проекту, добавьте пользовательский элемент управления в приложение WPF и просмотрите редактор категорий в действии.

Тестирование редактора категорий

  1. Добавьте к решению новый проект приложения WPF на языке Visual C# с именем DemoApplication.

    Файл MainWindow.xaml будет открыт в сред. Конструктор WPF.

  2. Добавьте ссылку на проект CustomControlLibrary.

  3. В представлении XAML для MainWindow.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>
    
  4. В представлении конструктора выберите элемент управления.

  5. В окне Свойства найдите категорию Text.

    Должен отобразиться пользовательский интерфейс для описания свойств категории "Text", отличный от других элементов управления. В раскрывающемся списке можно выбрать имя и размер шрифта. Установив флажки, можно выбрать полужирный или курсивный шрифт.

  6. Выполните изменение свойств, представленных в данной категории. Обратите внимание, что эти изменения отражаются в элементе управления.

См. также

Задачи

Пошаговое руководство. Реализация редактора цвета

Практическое руководство. Создание редактора значений

Другие ресурсы

Создание пользовательских редакторов

Расширяемость среды конструктора WPF