Форум программистов, компьютерный форум, киберфорум
Наши страницы
Wolflind
Войти
Регистрация
Восстановить пароль
Оценить эту запись

Панель кнопок

Запись от Wolflind размещена 08.09.2018 в 11:05
Метки c#, winforms

Не по теме:

Данную тему я перенес с форума можно посмотреть тут



В компании где я работаю есть программа, которую делали много разных людей в разное время
основная форма состоит из набора кнопок и меню с кнопками.
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");
        }
    }


после чего собрать проект после чего эти элементы появятся в панели элементов.
Так как создания кнопок происходит при инициализации объекта поэтому в редакторе формы мы сразу видим кнопки, которые там будут. Что возможно добавлю это чтоб формы запускались в отдельных потоках так как некоторые формы написаны достаточно криво и пока не добрался до них чтоб основная форма не зависали и не вылетала
Кликните здесь для просмотра всего текста

Нажмите на изображение для увеличения
Название: Снимок3.PNG
Просмотров: 99
Размер:	32.8 Кб
ID:	5028


А если понадобится добавить кнопку достаточно в класс добавить еще 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 цвета размеры и другие характеристики, но я делал под конкретную задачу и решил выложить вдруг кому пригодится

в итоге это выглядит так в редакторе

Кликните здесь для просмотра всего текста

Нажмите на изображение для увеличения
Название: Снимок.PNG
Просмотров: 106
Размер:	23.3 Кб
ID:	5026


в программе

Кликните здесь для просмотра всего текста

Нажмите на изображение для увеличения
Название: Снимок2.PNG
Просмотров: 100
Размер:	31.4 Кб
ID:	5027
Размещено в Без категории
Просмотров 200 Комментарии 0
Всего комментариев 0
Комментарии
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru