Главная » C#, Компоненты » Контейнеры

0

Процесс разработки формы заключается в расположении компонентов на форме или на других компонентах. Другими словами, каждый компонент и сама форма (вообще говоря, форма тоже является компонентом) являются контейнерами (container), которые могут содержать один или несколько компонентов. Для реализации такой возможности предусмотрен интерфейс System. ComponentModel.IContainer:

public interface IContainer : IDisposable (

ComponentCollection Components {get;} void Add(IComponent component); void Add(IComponet component, string name); void Remove(IComponent component);

Свойство components возвращает коллекцию компонентов, которые содержит контейнер. Методы Add о позволяют добавить компонент в конец списка компонентов, а метод Remove о — удалить указанный компонент из контейнера. Обратите внимание, что методов Add () два. Первый добавляет безымянный компонент, а второй— компонент с известным именем1. К компонентам, содержащимся в коллекции Components, можно обращаться как по имени, так и по индексу:

Component cl = container.Components["tl"] as Component; Component c2 = container.Components[0] as Component;

Замечу, что имя компонента должно быть уникально в рамках контейнера. Кроме того, в имени не различаются большие и маленькие буквы, т. е. имена tl и Т1 будут считаться одинаковыми. При попытке добавить два компонента С одинаковым именем генерируется исключение System. ArgumentException. Для проверки уникальности имени контейнер вызывает виртуальный метод protected virtual void ValidateName(IComponent component, string name)

Базовым классом, реализующим интерфейс icontainer, является класс

System.ComponentModel.Container.

Каждый контейнер сам заботится об освобождении всех содержащихся в нем компонентов. Посмотрите на листинг 4.1, результатом его работы будут следующие строки:

Метод Dispose: number=2 Метод Dispose: number=l

Метод Dispose () компонентов, добавленных в контейнер, был вызван автоматически при освобождении самого контейнера.

Понятно, что компонент сам по себе имени не имеет, оно появляется только при добавлении компонента в контейнер, например, при помещении компонента на форму. Для связи контейнера и компонента служит интерфейс isite:

public interface ISite : IServiceProvider {

// Ссылка на компонент IComponent Component { get; } // Ссылка на контейнер IContainer Container { get; }

// True, если режим разработки; false, если режим выполнения bool DesignMode { get; }

// Имя компонента или null, если компонент не имеет имени string Name { get; set; }

1

В самом компоненте этот интерфейс можно получить с помощью виртуального свойства site:

public class Component : MarshalByRefObject, IComponent, IDisposable i

public virtual ISite Site { get; set; )

1

Для компонентов, содержащих другие компоненты (не обязательно визуально), имеется класс NestedContainer, реализующий интерфейс INestedContainer:

public interface INestedContainer : IContainer, IDisposable 1

IComponent Owner { get; }

{

public class NestedContainer :

Container, INestedContainer, IContainer, IDisposable

{

// Конструктор

public NestedContainer(IComponent owner);

// Возвращает компонент-владелец public IComponent Owner { get; }

// Возвращает имя компонента-владельца protected virtual string OwnerName { get; )

}

Соответственно, такой контейнер создается "на базе" некоторого существующего компонента:

TestComponent owner = new TestComponent (0) ;

using (NestedContainer container = new NestedContainer(owner)) (

// Добавляем компоненты в контейнер

}

В остальном класс NestedContainer совпадает с обычным классом контейнера

Container.

Листинг 4.1. Контейнер заботится об освобождении ресурсов

using System;

using System.Collections.Generic;

using System.Text;

using System.ComponentModel;

namespace Conteiner {

class Program {

static void Main(string[] args) (

// Создаем контейнер

using (Container container = new Container()) {

// Добавляем компонент tl TestComponent tl = new TestComponent(1); container.Add(tl, "tl"); // Добавляем компонент t2 TestComponent t2 = new TestComponent(2); container.Add(t2, "t2");

}

// Контейнер будет освобожден при выходе из блока using. // Дополнительное освобождение tl и t2 не требуется

{

(

class TestComponent : Component {

private int number;

public TestComponent(int number) {

this.number = number;

{

protected override void Dispose(bool disposing) {

Console.WriteLine("Метод Dispose: number=(0}", number); base.Dispose(disposing);

{

(

{

Литература:

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

По теме:

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