Главная » C#, Компоненты » Взаимодействие с палитрой компонентов

0

Само по себе взаимодействие с палитрой компонентов (Toolbox) обычному компоненту не требуется. Скорее всего, такая возможность нужна дизайнеру формы. Но, тем не менее, это может оказаться полезным и в других случаях. В этом разделе я расскажу о сервисе TooiboxServi.ee, который позволяет не только получать информацию о зарегистрированных компонентах и управлять палитрой компонентов, но и программно добавлять компоненты на форму. Сервис TooiboxService имеет следующие свойства и методы (приведены только самые интересные):

?    СВОЙСТВО CategoryNameCollection CategoryNames возвращает коллекцию имен категорий в палитре компонентов;

О свойство string SeiectedCategory позволяет получать и устанавливать выбранную категорию; О метод ToolboxItemCollection GetToolboxItems (string category) возвращает коллекцию компонентов указанной категории;

?    метод void SetSelectedToolboxItem(Toolboxltem toolboxltem) выбирает категорию;

О метод Toolboxltem GetSelectedToolboxItemO возвращает выбранный компонент.

Таким образом, категории палитры компонентов описываются именами, а каждый компонент — классом Toolboxltem. Этот класс содержит следующие поля:

О AssembiyName AssembiyName — возвращает описание сборки, содержащей компонент;

О Bitmap Bitmap— возвращает картинку компонента;

О string company— возвращает авторскую информацию о компоненте (если она указана);

О AssembiyName [ ] DependentAssemblies — возвращает СПИСОК сборок, необходимых ДЛЯ работы компонента; О string Description — возвращает описание компонента (если оно указано); О string DispiayName — возвращает имя компонента, как его видно в палитре компонентов; О string TypeName — возвращает имя типа;

?    virtual string version — возвращает версию компонента (если она указана).

Компонент, приведенный в листинге 7.15, содержит два списка ListBox. В первый будет заноситься список категорий, а во второй — список компонентов категории, выбранной в первом списке. Кроме того, при выборе категории из списка категорий она будет автоматически выбираться в палитре компонентов. По двойному щелчку на строке в списке компонентов выбранный компонент будет добавляться на форму так, как будто его перетащили с палитры компонентов. Вся описанная функциональность достаточно проста и понятна из кода (это простые вызовы методов, которые я описал ранее), кроме программного создания компонента, о котором я расскажу чуть подробнее.

Итак, выбранный компонент дает нам объект типа Tooiboxitem. Теперь нам нужна сама форма. Получить ее можно с помощью метода FindFormO: Form parentForm = this. FindFormO ;

Хост формы получается с помощью метода GetService о с параметром

IDesignerHost:

IDesignerHost parentHost = (IDesignerHost) parentForm.. Site .GetService ( typeof (IDesignerHost));

Метод createcomponents о класса Tooiboxitem создает нужные нам компоненты:

components = item.CreateComponents(parentHost);

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

for (int i = 0; i < components.Length; i++)

{

// Если это видимый компонент

if (components[i].GetType().IsSubclassOf(typeof(Control)))

{

// Меняем его расположение ((Control)components[i]).Location -

new Point(20 * controlSpacingMultiplier, 20 * controlSpacingMultiplier); if (controlSpacingMultiplier > 10)

controlSpacingMultiplier = 0; else

controlSpacingMultiplier++;

// Регистрируем его в списке компонентов формы parentForm.Controls.Add((Control)components[1]);

}

}

Вид получившегося компонента показан на рис. 7.8. Слева видны четыре последовательно СОЗДаННЫХ компонента Типа CheckBox.

Рис. 7.8. Компонент ToolboxServiceControl

Листинг 7 15 Взаимодоистнис с политроп компонснюп

using System;

using System.Collections;

using System. ComponentModel;

using System.ComponentModel.Design;

using System. Drawing;

using System. Drawing. Design;

using System.Data;

using System.Diagnostics;

using System.Windows.Forms;

using System.Windows. Forms. Design;

namespace ToolboxServiceExample

{

[DesignerAttribute(typeof(WindowMessageDesigner), typeof(IDesigner))]

public class ToolboxServiceControl : UserControl

{

// Для хранения списка категорий

private ListBox categoryNames;

// Для хранения списка компонентов

private ListBox componentNames;

// Интерфейс сервиса IToolboxService

private IToolboxService toolboxService = null;

// Сдвиг координат. Используется для

// добавления компонентов на форму.

private int controlSpacingMultiplier;

// Инициализация

public ToolboxServiceControl()

{

InitializeComponent(); controlSpacingMultiplier = 0;

}

// Свойство Site устанавливается не равным null, // если мы в режиме разработки public override ISite Site

{

get {

return base.Site;

}

set

{

base.Site = value;

// В режиме разработки получаем интерфейс сервиса

if {base.Site != null) {

toolboxService = (IToolboxService)this.GetService(

typeof(IToolboxService)); // Если удалось получить сервис, получаем список категорий // и компонентов в категории if (toolboxService != null)

{

UpdateCategoryLists();

}

}

else {

toolboxService = null;

}

}

}

// Обновляем список категорий

private void UpdateCategoryLists{)

{

try

{

categoryNames.BeginUpdate();

if (toolboxService != null}

{

// Повторно создаем список категорий categoryNames.Items.Clear{};

for (int i = 0; i < toolboxService.CategoryNames.Count; i++} {

categoryNames.Items.Add(

toolboxService.CategoryNames[i]);

// Если зто текущая выбранная категория if (toolboxServiсе.CategoryNamesfi] ==

toolboxService.SelectedCategory)

{

// Сохраняем ее и выбираем ее в listbox categoryNames.Selectedlndex = i; П Создаем список компонентов в ней UpdateComponentList{);

}

}

}

}

finally

{

categoryNames.EndUpdate{)/

// Обновляем список компонентов в выбранной категории

private void UpdateComponentList()

{

try

{

componentNames.BeginUpdate(); componentNames.Items.Clear() ;

ToolboxItemCollection tools = toolboxService.GetToolboxltems ( toolboxService.SelectedCategory);

if {tools != null)

{

for (int j =0; j < too’ls. Count; j++) {

componentNames.Items.Add(tools[j].DisplayName);

}

)

}

finally {

componentNames.EndUpdate();

}

)

// Если выбрали новую категорию, // обновляем список компонентов в ней private void UpdateSelectedCategory(

object sender, System.EventArgs e)

{

if (toolboxService != null) {

// Меняем текущую выбранную категорию // в палитре компонентов toolboxService.SelectedCategory =

(string)categoryNames.Selectedltem; UpdateComponentList();

// Выбрали другой компонент,

// обновляем текущий компонент в палитре компонентов private void QpdateSelectedltem(object sender,

System.EventArgs e)

{

if {toolboxService != null) {

// Если есть выбранная категория if (categoryNames.Selectedlndex !— -1) i

// Компонент в текущей категории

if ((string)categoryNames.Selectedltem =

toolboxService.SelectedCategory)

{

ToolboxItemCollection tools =

toolboxService.GetToolboxItems(

toolboxService.SelectedCategory); toolboxService.SetSelectedToolboxItem(

tools[componentNaraes.Selectedlndex]);

}

//else

// Обновляем список категорий // UpdateCategoryLists();

}

\

// Двойной щелчок на имени компонента создает компонент private void CreateComponent(object sender, EventArgs e) (

// Текущий компонент в палитре компонентов

Toolboxltem item – toolboxService.GetSelectedToolboxItem();

// Ничего не выбрано — выход if (item — null) return;

// Получаем форму

Form parentForm = this.FindFormO ; if (parentForm = null) return;

// Получаем хост формы IDesignerHost parentHost =

(IDesignerHost)parentForm.Site.GetService(

typeof(IDesignerHost));

if (parentHost — null) return;

// Создаем компонент lComponent[] components = null;

try

{

components = item.CreateComponents(parentHost);

}

catch (Exception ex)

{

MessageBox»Show(ex.ToString(), "Ошибка");

}

// he получилось создать — выхоХеим if (components = null) return;

// Располагаем видимые компоненты на форме

for (int i = 0; i < components.Length; i++) {

// Если это видимый компонент

if (components[i].GetType().isSubclassOf(typeof(Control))) {

// Меняем его расположение {(Control)components[i]).Location =

new Point{20 * controlSpacingMultiplier, 20 * controlSpacingMultiplier); if (controlSpacingMultiplier > 10)

controlSpacingMultiplier = 0; else

controlSpacingMultiplier++; // Регистрируем его в списке компонентов формы parentForm.Controls.Add((Control)components[i]);

}

}

}

// Показать строки

protected override void OnPaint(PaihtEventArgs e)

{

SolidBrush blackBrush = new SolidBrush(Color.Black); e.Graphics.Drawstring("Компонент ToolboxServiceControl",

new Font("Arial", 14), blackBrush, 6, 4); e.Graphics.Drawstring{"категории",

new Font("Arial", 8), blackBrush, 8, 26);

е.Graphics.Drawstring("Компоненты",

new Font("Arial", 8), blackBrush, 208, 26);

}

private void InitializeComponent{)

{

this.categoryNames = new ListBox(); this.componentNames = new ListBoxO; this.SuspendLayout{);

this.categoryNames.Location = new System.Drawing.Point (8, 41); this.categoryNames.Name = "categoryNames";

this.categoryNames.Size = new System.Drawing.Size(192, 368) ;

this.categoryNames.Tablndex = 0;

this.categoryNames.SelectedindexChanged +=

new System.EventHandler(this.UpdateSelectedCategory); this.componentNames.Location = new System.Drawing.Point(208, 41); this.componentNames.Name = "componentNames";

this.componentNames.Size = new System.Drawing.Size(228, 368);

this.componentNames.Tablndex = 3;

this.componentNames.SelectedindexChanged +=

new System.EventHandler(this.UpdateSelectedltem); this.componentNames.Doubleclick +=

new EventHandler(this.CreateComponent); this.BackColor = System.Drawing.Color.Beige; this.Controls.AddRange(new Control[] { this.componentNames, this.categoryNames}) ; this.Location = new System.Drawing.Point(500, 400); this.Name — "ToolboxServiceControl"; this.Size = new System.Drawing.Size(442, 422); this.ResumeLayout(false);

}

}

// Специальный дизайнер позволяет работать с двумя ListBox // внутри компонента как в режиме выполнения, / / например, прокручивать элементы

public class WindowMessageDesigner : ControlDesigner {

public WindowMessageDesigner() {

}

// Передаем сообщения Windows в дизайнер

protected override void WndProc(ref Message message) {

if {message.HWnd — this.Control.Handle)

base.WndProc(ref message); else

this.DefWndProc(ref message);

}

)

}

Литература:

Агуров П. В. C#. Разработка компонентов в MS Visual Studio 2005/2008. – СПб.: БХВ-Петербург, 2008. — 480 е.: ил.

По теме:

  • Комментарии