Не по теме:
Данную тему я перенес с форума можно посмотреть тут
В компании где я работаю есть программа, которую делали много разных людей в разное время
основная форма состоит из набора кнопок и меню с кнопками.
90% этих кнопок все что делает открывает другие формы и программы выглядят примерно так
| C# | 1
2
3
4
5
| private void button1_Click_1(Object sender, EventArgs e)
{
Form form = new Form();
form.Show();
} |
|
все кнопки разного размера в этой форме почто 1000 строк такова кода
Да можно было все упростить до
| C# | 1
2
| private void button1_Click_1(Object sender, EventArgs e)
new Form().Show(); |
|
но кнопки периодически добавляются, но практически не удаляются из-за того, что проверить для чего нужна каждая кнопка тяжело а если и удалить то все кнопки нужно сдвигать и количество строк это особо не уменьшит в основной форме
я решил немного прибраться в коде и был написан такой класс
Кликните здесь для просмотра всего текста
| C# | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
| public abstract class ButtonPanel : UserControl
{
public ButtonPanel() => ButtonPanelInitialize();
private void ButtonPanelInitialize()
{
SuspendLayout();
flowLayoutPanel.Dock = DockStyle.Fill;
flowLayoutPanel.FlowDirection = FlowDirection.TopDown;
flowLayoutPanel.Padding = new Padding(5);
flowLayoutPanel.TabIndex = 0;
AutoScaleMode = AutoScaleMode.Font;
GeneratorButton();
Controls.Add(flowLayoutPanel);
ResumeLayout(false);
}
private FlowLayoutPanel flowLayoutPanel = new FlowLayoutPanel();
protected void ShowForm<T>() where T : Form, new() => new T().Show();
protected void AddButton<T>(String name) where T : Form, new() =>
AddButton(name, () => ShowForm<T>());
protected void AddButton(String name, Type type) =>
AddButton(name, () => ((Form)Activator.CreateInstance(type)).Show() );
protected void AddButton(String name, Action action)
=> AddButton(name, (o, e) => action());
protected void AddButton(String name, EventHandler action)
{
Button button = new Button
{
Size = new Size(180, 40),
Text = name
};
button.Click += action;
flowLayoutPanel.Controls.Add(button);
}
public abstract void GeneratorButton();
} |
|
этот класс по сути создает панельки с копками.
Как им пользоваться?
Да очень просто достаточно создать, например, такие классы.
Кликните здесь для просмотра всего текста
| C# | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| public partial class UserControl1 : ButtonPanel
{
public override void GeneratorButton()
{
AddButton<Form>("Пример0");
AddButton<Form>("Пример1");
AddButton<Form>("Пример2");
AddButton<Form>("Пример3");
AddButton<Form>("Пример4");
AddButton<Form>("Пример5");
AddButton<Form>("Пример6");
AddButton<Form>("Пример7");
AddButton<Form>("Пример8");
}
}
public partial class UserControl2 : ButtonPanel
{
public override void GeneratorButton()
{
AddButton<Form>("Пример01");
AddButton("Пример11",() => MessageBox.Show("Пример11"));
AddButton("Пример21", (o,s) => MessageBox.Show("Пример11" + o.GetType().Name));
AddButton("Пример31", typeof(Form));
AddButton("Пример41", Test);
}
private void Test()
{
MessageBox.Show("Пример41");
}
}
public partial class UserControl3 : ButtonPanel
{
public override void GeneratorButton()
{
AddButton<Form>("Пример02");
AddButton<Form>("Пример12");
AddButton<Form>("Пример22");
AddButton<Form>("Пример32");
}
} |
|
после чего собрать проект после чего эти элементы появятся в панели элементов.
Так как создания кнопок происходит при инициализации объекта поэтому в редакторе формы мы сразу видим кнопки, которые там будут. Что возможно добавлю это чтоб формы запускались в отдельных потоках так как некоторые формы написаны достаточно криво и пока не добрался до них чтоб основная форма не зависали и не вылетала
Кликните здесь для просмотра всего текста
А если понадобится добавить кнопку достаточно в класс добавить еще 1 строку, например, такую
AddButton<Form>("Пример10") и снова собрать проект, и новая кнопка появится.
Для тех, кто не понимает, как это работает.
Основные методы это AddButton, которые создают кнопки.
1. Создает кнопку из названия и делегата EventHandler который используется в событии Click
| C# | 1
2
3
4
5
6
7
8
9
10
| protected void AddButton(String name, EventHandler action)
{
Button button = new Button
{
Size = new Size(180, 40),
Text = name
};// создаем кнопку
button.Click += action;// привязываем делегат к событию
flowLayoutPanel.Controls.Add(button);
} |
|
2.Этот метод нужен только для упрощения чтоб не нужно было передавать методы вот так (o, e) => action() а просто передать метод без аргументов вот так AddButton(“название”, action )
| C# | 1
2
| protected void AddButton(String name, Action action)
=> AddButton(name, (o, e) => action()); |
|
2. Этот метод принимает названия также обобщённый тип формы и ее наследников
на это нам указывает ограничения where T : Form
new() нам говорит что что этот класс содержит общедоступный конструктор без параметров
подробней можно прочитать по этим ссылкам
тут и тут
этот метод всего лишь запускает метод AddButton с другими параметрами и передает в него
название, а также функцию ShowForm здесь обобщение нужно для метода ShowForm
| C# | 1
2
| protected void AddButton<T>(String name) where T : Form, new() =>
AddButton(name, () => ShowForm<T>()); |
|
Этот метод запускает форму, но как он это делает
Тут нам каркас и понадобится обобщения которое позволит создать форму и отобразить ее
Но как она это делает все достаточно просто <T> это класс формы или ее наследника как программа это определила и тут нам как раз пригождается ограничения
new() которая позволяет создать новый экземпляр класса и ограничении where T : Form говорит, что T является формой или ее наследника благодаря чему мы можешь воспользовался методами этого класса в данном случаи нам интересен именно метод Show() который и позволит отобразить форму
| C# | 1
| protected void ShowForm<T>() where T : Form, new() => new T().Show(); |
|
этот метод не менее интересен в нем используется статический Activator и его класс метод CreateInstance который позволяет создать объект по его типу после чего мы преобразовываем его пытаемся преобразовать в тип Form и если type получится преобразовать форм то показываем ее а если нет то получим значения null для того чтобы не получить ошибку мы используем оператор “?” (как он работает можно прочитать тут )
Этот метод создан для примера как еще это можно реализовать.
Я пользуюсь методом AddButton<T>(Strin name), так как он более удобен в использовании, а в этом методе придётся воспользоваться методом typeof() или object.GetType() для передачи типа
| C# | 1
2
| protected void AddButton(String name, Type type) =>
AddButton(name, () => ((Form)Activator.CreateInstance(type)).Show() ); |
|
Также можно данный класс улучшить, например, добавив в методы AddButton цвета размеры и другие характеристики, но я делал под конкретную задачу и решил выложить вдруг кому пригодится
в итоге это выглядит так в редакторе
Кликните здесь для просмотра всего текста
в программе
Кликните здесь для просмотра всего текста
|