Создание собственных элементов управления

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

Создавать новые элементы управления можно тремя способами:

  1. создание элемента управления с нуля;

  2. создание нового элемента за счёт расширения возможностей существующего элемента;

  3. создание нового элемента управления на базе совокупности существующих элементов.

Рассмотрим каждый из способов подробнее.

1.Создание элемента управления с нуля

В этом случае элемент управления пользователя создаётся на основе класса Control. Это наиболее трудоёмкий путь решения задачи. Используется тогда, когда в коллекции готовых элементов управления нет ничего подходящего, близкого для решения стоящей проблемы.

Разработка собственного элемента управления начинается с создания оконного приложения. Затем из проекта надо удалить файл Program.cs, удалить файл MainForm.Designer.cs, и в файле MainForm.cs в области имён (в примере ниже — это Prim_Lampa) удалить класс WindowsForm, вместо него создаём свой класс, реализующий необходимый функционал.

Затем изменим тип проекта. Выбираем пункт меню Project/ Project Options... и во вкладке Application меняем Output type (тип проекта) на Class Library.

Пример 1. Разработать элемент управления, моделирующий поведения лампы. Щелчок по лампе включает её (жёлтый цвет) или выключает (серый цвет).

Текст элемента управления:

using System;

using System.Collections.Generic;

using System.Drawing;

using System.Windows.Forms;


namespace Prim_Lampa

{

   public class Lampa: Control

   {

      int w;

      int h;

      bool vk;


      public Lampa()

      {

         w = 50;

         h = 50;

         vk = true;

      }


      protected override void OnClick(EventArgs e)

      {

         base.OnClick(e);

         vk = !vk;

         Invalidate();

      }


      protected override void OnPaint(PaintEventArgs e)

      {

         base.OnPaint(e);

         Graphics g = e.Graphics;

         if(vk)

            g.FillEllipse(Brushes.Yellow,0,0,w,h);

         else

            g.FillEllipse(Brushes.Gray,0,0,w,h);

      }

   }

}


Пояснение к тексту класса Lampa.

В классе используется три поля:

Имеется конструктор для инициализации полей класса и два метода:

Проект для данного элемента управления необходимо откомпилировать. Затем можно создать оконное приложение (пример — см. ниже) и подключить элемент управления в панель инструментов. Если он не появится автоматически, то выбираем пункт меню Project/Add Reference. В открывшемся окне диалога выбираем вкладку .NET Assembly Browser, затем нажимаем кнопку Browse..., находим наш элемент управления и подключаем его. Элемент управления должен появится в списке элементов управления в группе Custom Components.

Новый элемент управления устанавливаем на форме и запускаем программу на выполнение.

Текст программы для тестирования элемента управления:

using System;

using System.Collections.Generic;

using System.Drawing;

using System.Windows.Forms;


namespace Test_Prim_Lampa

{

   public partial class MainForm : Form

   {

      public MainForm()

      {

         InitializeComponent();

      }

   }

}

2.Расширения возможностей существующего элемента

Создание нового элемента на базе существующего — это один из наиболее простых способов создания элемента с необходимыми возможностями. Применяется в том случае, когда уже существует элемент, близкий по своим параметрам к тому, что требуется, но ему не хватает каких-то свойств.

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

Пример 2. Разработаем элемент управления, предназначенный для ввода с клавиатуры отдельных слов на русском языке. За основу возьмём «ближайшего родственника»: TextBox.

Текст элемента управления:

using System;

using System.Collections.Generic;

using System.Drawing;

using System.Windows.Forms;


namespace Control_Text_Edit

{

   public class TextEditRu: TextBox

   {

      string sR="АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";

      string sr="абвгдеёжзийклмнопрстуфхцчшщъыьэюя";


      public TextEditRu():base()

      { }


      protected override void OnKeyPress(KeyPressEventArgs e)

      {

         base.OnKeyPress(e);

         char c = e.KeyChar;

         if(sr.IndexOf(c)>=0 || sR.IndexOf(c)>=0)

         {

            e.Handled = false;

            return;

         }

         if(Convert.ToInt32(c) == 8)

         {

            e.Handled = false;

            return;

         }

         e.Handled = true;

      }


      public override string Text

      {

         get

         {

            return base.Text;

         }

         set

         {

            base.Text = value;

         }

      }

   }

}


Пояснение к тексту класса TextEditRu.

В классе используется конструктор, перегруженный метод OnKeyPress() и свойство Text.

Метод OnKeyPress() предназначен для того, чтобы не допускать ввода ни каких символов, кроме букв русского алфавита. В этом методе надо обратить на два свойства:

Конструктор тривиален, свойство Text необходимо для того, чтобы прочитать или записать текст в свойство Text базового класса TextBox.

Применение объектов типа TextEditRu такое же, как и объектов базового класса TextBox. Только наш класс TextEditRu имеет свою специализацию: позволяет вводить исключительно буквы русского алфавита.

3.Компонент как совокупность существующих элементов

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

Пример 3. Среди готовых элементов управления нет элемента для удобного ввода данных в массив. Разработаем такой элемент. Считаем, что с помощью данного элемента мы будем вводить с клавиатуры массивы чисел типа double, int и массивы строк.

Последовательность действий следующая: выбираем Новый проект New Project, задаём тип проекта Windows User Control Library, задаём название проекту, например Control_2_User и нажимаем кнопку Create (Создать).

Будет создана заготовка класса UserControl1. Добавим для него поле типа ArrayList для хранения списка введённых с клавиатуры элементов и свойство Mas типа ArrayList для чтения коллекции из элемента управления.

Затем на пустой заготовке-контейнере размещаем необходимые элементы.

Вот внешний вид элемент управления для ввода массива:



Вверху располагается элемент типа GroupBox с надписью «Ввод массива типа», в нём три элемента типа RadioButton для выбора типа элементов массива.

Ниже надпись (label1) с текстом «x[i]», поясняющая, какой элемент по счёту будет вводится, и текстовое поле textBox1 для ввода элемента массива.

Кнопка button1 («Добавить») используется для добавления нового элемента в список, кнопка button2 («Очистить») — для очистки списка.

Внизу располагается текстовое поле textBox2 для печати всех введённых элементов списка.

Текст элемента управления:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Drawing;

using System.Windows.Forms;

using System.Collections;


namespace Control_2_User

{

   public partial class UserControl1: UserControl

   {

      ArrayList x = new ArrayList();


      public UserControl1()

      {

         InitializeComponent();

      }


      public ArrayList Mas

      {

         get{

            return x;

         }

      }


      void Button1Click(object sender, EventArgs e)

      {

         if(radioButton1.Checked)

            x.Add(double.Parse(textBox1.Text));

         else if(radioButton2.Checked)

            x.Add(int.Parse(textBox1.Text));

         else if(radioButton3.Checked)

            x.Add(textBox1.Text);

         label1.Text="X["+(x.Count)+"]=";

         if(x.Count>1)

            textBox2.Text+=", "+textBox1.Text;

         else

            textBox2.Text=textBox1.Text;

         textBox1.Text="";

         Invalidate();

      }


      void Button2Click(object sender, EventArgs e)

      {

         x.Clear();

         textBox1.Text="";

         textBox2.Text="";

         label1.Text="X["+0+"]=";

         Invalidate();

      }

   }

}


Теперь напишем программу для тестирования элемента управления. Создадим новое оконное приложение. На форме разместим наш элемент управления, кнопки Button для вызова обработчиков и элементы Label для вывода результатов тестирования. Вот внешний вид формы:






Текст программы для тестирования элемента управления:

using System;

using System.Collections.Generic;

using System.Drawing;

using System.Windows.Forms;

using System.Collections;

namespace Test_Control_2_User

{

   public partial class MainForm : Form

   {

      public MainForm()

      {

         InitializeComponent();

      }


      void Button2Click(object sender, EventArgs e)

      {

         Close();

      }


      // Сумма вещественных чисел

      void Button1Click(object sender, EventArgs e)

      {

         int n = userControl11.Mas.Count;

         double[]x=new double[n];

         userControl11.Mas.CopyTo(x);

         double s=0;

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

            s+=x[i];

         label1.Text="s="+s;

      }


      // Максимум в массиве целых чисел

      void Button3Click(object sender, EventArgs e)

      {

         int n = userControl11.Mas.Count;

         int[]x=new int[n];

         userControl11.Mas.CopyTo(x);

         int max=x[0];

         for(int i=1; i<n; i++)

            if(x[i]>max)

               max=x[i];

         label2.Text="max="+max;

      }


      //Поиск заданного слова (Red) в массиве строк

      void Button4Click(object sender, EventArgs e)

      {

         string s = "Red";

         int n = userControl11.Mas.Count;

         string[]x=new string[n];

         userControl11.Mas.CopyTo(x);

         bool p = false;

         for(int i=0; i<n; i++)

            if(x[i]==s)

            {

               p = true;

               break;

            }

         if(p)

            label3.Text="Найдено слово Red";

         else

            label3.Text="Слово Red не найдено";

      }

   }

}



В данной программе мы тестируем работу элемента управления при вводе вещественных чисел, целых чисел и строк.

Обратите внимание на то, как мы получаем данные из элемента управления:

1)Определяем количество элементов в коллекции:

    int n = userControl11.Mas.Count;

2)Создаём массив нужного размера:

    double[]x=new double[n];

3)Копируем данные из коллекции в наш массив x:

    userControl11.Mas.CopyTo(x);

После этого с массивом x можно делать всё, что потребуется.



Назад
На верх
Вперёд
Hosted by uCoz