| Украина, Киев |
Пользовательские компоненты
Упражнение 2. Создание невизуального компонента Planets
В этом примере мы создадим невизуальный компонент Planets, инкапсулирующий в себе названия планет Солнечной системы, и добавим его в нашу библиотеку компонентов сборки MyComponents. Названия планет будут храниться во внутреннем массиве компонента, а доступ к ним будет осуществляться через индексаторы по имени планеты или ее индексу.
-
В панели Solution Explorer выделите проект MyComponents и
выполните команду меню Project/Add Component,
чтобы добавить файл Planets.cs нового
компонента -
Дополните
содержимое файла, автоматически сгенерированное мастером,
следующим кодом
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Collections;
namespace MyCompany.MyComponents
{
public partial class Planets : Component
{
public Planets()
{
InitializeComponent();
}
public Planets(IContainer container)
{
container.Add(this);
InitializeComponent();
}
}
}
namespace MyCompany.MyComponents
{
partial class Planets
{
// Планеты
private string[] PlanetNames ={ "Меркурий",
"Венера",
"Земля",
"Марс",
"Юпитер",
"Сатурн",
"Уран",
"Нептун",
"Плутон"
};
// Вернуть имя
private string GetPlanetName(int index)
{
// Нижняя и верхняя границы массива
int lowP = 0, highP = PlanetNames.Length - 1;
// Контролирует диапазон индекса планеты и возвращает
// ее название или генерирует исключение
if (index < lowP || index > highP)
{
MessageBox.Show(String.Format("Индекс должен находиться в диапазоне {0}-{1}",
lowP, highP));
index = 0;
}
return PlanetNames[index];
}
// Вернуть индекс
private int GetPlanetPosition(string planetName)
{
// Сравниваем переданное имя планеты с массивом
// PlanetNames. При несовпадении возвращаем -1
int result=-1;
for(int i=0; i<PlanetNames.Length;i++)
if (String.Compare(planetName, PlanetNames[i], true) == 0)
{
result = i;
break;
}
return result;
}
// Свойство - индексатор: возвращает имя планеты по индексу
public string this[int index]
{
get {return GetPlanetName(index); }
}
// Свойство - индексатор: возвращает индекс планеты по имени
public int this[string planetName]
{
get { return GetPlanetPosition(planetName); }
}
// Свойство максимального размера массива
public int MaxIndex
{
get { return PlanetNames.Length - 1; }
}
}
}
Листинг
24.8.
Расширенное содержимое файла Planets.cs
В коде мы объявили массив с планетами и сразу инициализировали его. Создали два внутренних контролирующих метода, возвращающих название планеты по ее индексу и наоборот. Добавили два общедоступных свойства - индексатора, позволяющих работать с экземпляром компонента как с массивом, а также добавили общедоступное свойство максимального размера поля - массива с планетами.
Теперь осталось перекомпилировать сборку MyComponents.dll, в которой в одном пространстве имен MyCompany.MyComponents будут находиться уже два наших компонента, и испытать новый невизуальный компонент.
-
В панели Solution Explorer вызовите контекстное меню
для узла проекта MyComponets и выполните команду Rebuild,
чтобы перекомпилировать проект с компонентами -
Убедитесь,
что в панели Toolbox появился новый компонент Planets,
который теперь можно перетаскивать на форму также, как и
обычный библиотечный компонент
Испытание созданных компонентов
-
В проекте ComponentTest настройте пользовательский
интерфейс, как показано на рисунке и в таблице (в скобках
приведены имена экземпляров компонентов)
-
В панели Properties перейдите на вкладку Events и
создайте обработчики для элементов согласно таблицы
-
Заполните
файл Form1.cs следующим кодом
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace ComponentTest
{
public partial class Form1 : Form
{
// Конструктор формы
public Form1()
{
InitializeComponent();
// Заполнение списка планетами
for (int i = 0; i <= planets1.MaxIndex; i++)
{
listPlanets.Items.Add(String.Format(
"{0}) {1}", i, planets1[i]));
}
listPlanets.SelectedIndex = 0;
}
// Обработчики событий
private void firstComponent1_Click(object sender, EventArgs e)
{
// Контролируем пустой ввод
if (indexPlanet.Text == String.Empty) return;
int index = Convert.ToInt32(indexPlanet.Text);
// Контролируем максимальный индекс ввода
index = Math.Min(index, planets1.MaxIndex);
if (listPlanets.SelectedIndex != index)
listPlanets.SelectedIndex = index;
else
MessageBox.Show(String.Format("Вы выбрали планету {0}", planets1[index]));
}
private void indexPlanet_KeyPress(object sender, KeyPressEventArgs e)
{
// Фильтруем цифры, Backspace, Enter (Delete и стрелки по умолчанию)
if ((e.KeyChar < Convert.ToChar(Keys.D0) ||
e.KeyChar > Convert.ToChar(Keys.D9))
&& e.KeyChar != Convert.ToChar(Keys.Back)
&& e.KeyChar != Convert.ToChar(Keys.Enter))
e.Handled = true;
// Реакция на клавишу Enter
if (e.KeyChar == Convert.ToChar(Keys.Enter))
firstComponent1_Click(null, EventArgs.Empty);
}
bool loadFlag = true; // Локальное поле-флаг
private void listPlanets_SelectedValueChanged(object sender, EventArgs e)
{
int index = listPlanets.SelectedIndex;
indexPlanet.Text = index.ToString();
if (loadFlag)
{
// При первом запуске не показывать
loadFlag = false;
return;
}
else
MessageBox.Show(String.Format("Вы выбрали планету {0}", planets1[index]));
}
}
}
Листинг
24.9.
Код файла Form1.cs
-
Откомпилируйте
приложение текущего уровня готовности и испытайте его работу
