Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/11: Рейтинг темы: голосов - 11, средняя оценка - 5.00
9 / 9 / 5
Регистрация: 19.08.2016
Сообщений: 86

Какой это контрол?

19.08.2016, 13:31. Показов 2530. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Уважаемые Постояльцы и гости...Подскажите плиз, что это за контрол ???
Я начинаю делать первые шаги в программирование на СиШарп. )
Миниатюры
Какой это контрол?  
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
19.08.2016, 13:31
Ответы с готовыми решениями:

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

Как можно изменить слой, на котором находится контрол? Чтобы один контрол всегда рисовался поверх другого?
Просто я создаю контролы динамически, и при появлении они всегда ниже созданных ранее, это проблема. Заранее спасибо!

Как в дочерней форме определить какой контрол нажат в родительской форме
Есть textbox на дочерней форме и если на родительской форме нажат button1, то textbox остаётся со значением по умолчанию(какой-нибудь...

18
2810 / 1679 / 885
Регистрация: 14.04.2015
Сообщений: 5,723
19.08.2016, 19:01
видимо, самописный datagrid
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
19.08.2016, 20:02
Цитата Сообщение от KSTMK Посмотреть сообщение
Подскажите плиз, что это за контрол ???
Нечто подобное можно сделать с помощью PropertyGrid.
2
9 / 9 / 5
Регистрация: 19.08.2016
Сообщений: 86
20.08.2016, 05:38  [ТС]
Вчера нашел нечто подобное

https://habrahabr.ru/post/78024/
Будем пробовать прикручивать

Добавлено через 1 минуту
Действительно очень похож на PropertyGrid

Добавлено через 2 часа 21 минуту
Дорогого времени суток !)

Где можно скачать такой элемент управления, уж больно удобный, PropertyGrid не подходит для решения этой задачи (возиться дня три четыре) к тому же нужно будет все эти значения заносить и вытаскивать из БД.

Третий день гугл устает от меня)
0
9 / 9 / 5
Регистрация: 19.08.2016
Сообщений: 86
21.08.2016, 06:14  [ТС]
Доброго времени суток !!!

Подскажите или направьте в нужное русло...Как или какой элемент управления использовать для данного решения задачи ..
PropertyGrid не подходит ((( слишком уж замудрённо (
Миниатюры
Какой это контрол?  
0
Эксперт .NET
 Аватар для Usaga
14293 / 9378 / 1352
Регистрация: 21.01.2016
Сообщений: 35,360
21.08.2016, 06:26
KSTMK, скорее всего это обычный DataGridView. Просто вторая колонка имеет типа DataGridViewComboBoxColumn.
0
9 / 9 / 5
Регистрация: 19.08.2016
Сообщений: 86
21.08.2016, 07:42  [ТС]
вторая колонка (столбец) имеет разный тип...(Chekbox, TextBox, ComboBox, RichTextBox)
в левую колонку подтягиваются данные из БД (название столбцов), а в правую колонку значения столбцов (выборка из БД)
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
21.08.2016, 10:00
Цитата Сообщение от KSTMK Посмотреть сообщение
Подскажите или направьте в нужное русло...Как или какой элемент управления использовать для данного решения задачи ..
PropertyGrid не подходит ((( слишком уж замудрённо (
Так сами напишите... Там писать-то часа два...
0
9 / 9 / 5
Регистрация: 19.08.2016
Сообщений: 86
21.08.2016, 11:05  [ТС]
Спасибо за совет. Но я только начинаю осваивать C# Хотелось бы взглянуть краем глаза на исходники. Или подскажите с чего начинать и что использовать
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
21.08.2016, 11:38
Цитата Сообщение от KSTMK Посмотреть сообщение
Или подскажите с чего начинать и что использовать
Ну давайте, начнем. Создадим UserControl, назовем его RowDataGrid.
Также загрузим тестовую таблицу(DataTable) из SQLEXPRESS:
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
using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
 
namespace WindowsFormsApplication348
{
    public partial class Form1 : Form
    {
        DataTable table = new DataTable();
 
        public Form1()
        {
            InitializeComponent();
 
            //загружаем таблицу Orders из SQLEXPRESS
            using (var connection = new SqlConnection(@"Data Source=localhost\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True"))
            {
                connection.Open();
 
                using (var command = new SqlCommand("SELECT * FROM Orders", connection))
                {
                    table = new DataTable();
                    table.Load(command.ExecuteReader());
                }
            }
        }
    }
 
    /// <summary>
    /// Грид для редактирования одной строки таблицы
    /// </summary>
    public class RowDataGrid : UserControl
    {
    }
}
1
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
21.08.2016, 11:50
Далее, создадим свойство DataRow, которое будет принимать строку таблицы, которую нужно отобразить. Создадим метод Build() который будет строить внутренности контрола, в соответствии с колонками таблицы.
Сразу же посчитаем суммарную высоту внутренностей контрола, что бы настроить скролл:
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
 
namespace WindowsFormsApplication348
{
    public partial class Form1 : Form
    {
        DataTable table = new DataTable();
 
        public Form1()
        {
            InitializeComponent();
 
            //загружаем таблицу Orders из SQLEXPRESS
            using (var connection = new SqlConnection(@"Data Source=localhost\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True"))
            {
                connection.Open();
 
                using (var command = new SqlCommand("SELECT * FROM Orders", connection))
                {
                    table = new DataTable();
                    table.Load(command.ExecuteReader());
                }
            }
 
            //создаем наш контрол, присваиваем свойство DataRow
            var grid = new RowDataGrid(){Parent = this, Dock = DockStyle.Fill};
            grid.DataRow = table.Rows[0];
 
        }
    }
 
    /// <summary>
    /// Грид для редактирования одной строки таблицы
    /// </summary>
    public class RowDataGrid : UserControl
    {
        private const int RowHeight = 30;
 
        private DataRow dataRow;
        public DataRow DataRow
        {
            get { return dataRow; }
            set { dataRow = value; Build(); }
        }
 
        private List<DataColumn> columns = new List<DataColumn>();
 
        private void Build()
        {
            //получаем все столбцы таблицы
            columns = DataRow.Table.Columns.OfType<DataColumn>().ToList();
            //считаем внутренний размер контрола
            AutoScrollMinSize = new Size(0, RowHeight*(columns.Count + 1));
        }
    }
}
Название: Скриншот 2016-08-21 11.50.21.png
Просмотров: 66

Размер: 13.5 Кб
1
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
21.08.2016, 12:01
Рисуем сеточку грида:
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
    /// <summary>
    /// Грид для редактирования одной строки таблицы
    /// </summary>
    public class RowDataGrid : UserControl
    {
        private const int RowHeight = 30;
        private const int LeftColumnWidth = 200;
 
        private DataRow dataRow;
        public DataRow DataRow
        {
            get { return dataRow; }
            set { dataRow = value; Build(); }
        }
 
        private List<DataColumn> columns = new List<DataColumn>();
 
        public RowDataGrid()
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint, true);
        }
 
        private void Build()
        {
            //получаем все столбцы таблицы
            columns = DataRow.Table.Columns.OfType<DataColumn>().ToList();
            //считаем внутренний размер контрола
            AutoScrollMinSize = new Size(0, RowHeight*columns.Count + 1);
        }
 
        protected override void OnPaint(PaintEventArgs e)
        {
            if (columns == null || DataRow == null)
                return;
            //смещаем канву в соотв со скроллом
            e.Graphics.TranslateTransform(0, -VerticalScroll.Value);
            //рисуем грид
            for(int i=0;i<columns.Count + 2;i++)
            {
                var y = i*RowHeight;
                e.Graphics.DrawLine(Pens.Silver, 0, y, ClientSize.Width, y);
            }
            e.Graphics.DrawLine(Pens.Silver, LeftColumnWidth, 0, LeftColumnWidth, RowHeight * (columns.Count + 1));
        }
    }
1
9 / 9 / 5
Регистрация: 19.08.2016
Сообщений: 86
21.08.2016, 12:19  [ТС]
Сеточка )))) и скрол не появились (((

Добавлено через 7 минут
Все получилось !!!!!!!
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
21.08.2016, 12:20
Рисуем верхнюю шапку, рисуем названия полей и их значения:
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
    /// <summary>
    /// Грид для редактирования одной строки таблицы
    /// </summary>
    public class RowDataGrid : UserControl
    {
        private const int RowHeight = 30;
        private const int LeftColumnWidth = 200;
 
        private DataRow dataRow;
        public DataRow DataRow
        {
            get { return dataRow; }
            set { dataRow = value; Build(); }
        }
 
        private List<DataColumn> columns = new List<DataColumn>();
 
        public RowDataGrid()
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.ResizeRedraw, true);
        }
 
        private void Build()
        {
            //получаем все столбцы таблицы
            columns = DataRow.Table.Columns.OfType<DataColumn>().ToList();
            //считаем внутренний размер контрола
            AutoScrollMinSize = new Size(0, RowHeight*columns.Count + 1);
        }
 
        protected override void OnPaint(PaintEventArgs e)
        {
            if (columns == null || DataRow == null)
                return;
 
            var gr = e.Graphics;
 
            //смещаем канву в соотв со скроллом
            gr.TranslateTransform(0, -VerticalScroll.Value);
 
            //рисуем грид
            for(int i=0;i<columns.Count + 2;i++)
            {
                var y = i*RowHeight;
                gr.DrawLine(Pens.Silver, 0, y, ClientSize.Width, y);
            }
 
            //верт линия
            gr.DrawLine(Pens.Silver, LeftColumnWidth, 0, LeftColumnWidth, RowHeight * (columns.Count + 1));
 
            //
            var sf = StringFormat.GenericTypographic;
 
            //рисуем название полей и значения
            sf = StringFormat.GenericTypographic;
            sf.LineAlignment = StringAlignment.Center;
 
            for (int i = 0; i < columns.Count; i++)
            {
                var y = RowHeight*(i + 1);
                //поле
                sf.Alignment = StringAlignment.Far;
                var rect = new Rectangle(0, y, LeftColumnWidth, RowHeight);
                rect.Inflate(-4, -2);
                gr.DrawString(columns[i].ColumnName, Font, Brushes.Navy, rect, sf);
 
                //значение
                sf.Alignment = StringAlignment.Near;
                rect = new Rectangle(LeftColumnWidth, y, ClientSize.Width - LeftColumnWidth, RowHeight);
                rect.Inflate(-4, -2);
                var val = dataRow[i] ?? "";
                gr.DrawString(val.ToString(), Font, Brushes.Black, rect, sf);
            }
 
            //рисуем шапку
            gr.ResetTransform();
            using (var brush = new LinearGradientBrush(new Rectangle(0, 0, 10, RowHeight), Color.Gainsboro, Color.Silver, 90))
            {
                sf.Alignment = sf.LineAlignment = StringAlignment.Center;
 
                var rect = new Rectangle(0, 0, LeftColumnWidth, RowHeight);
                gr.FillRectangle(brush, rect);
                gr.DrawString("Поле", Font, Brushes.Black, rect, sf);
 
                rect = new Rectangle(LeftColumnWidth, 0, ClientSize.Width - LeftColumnWidth, RowHeight);
                gr.FillRectangle(brush, rect);
                gr.DrawString("Значение", Font, Brushes.Black, rect, sf);
            }
        }
 
        protected override void OnScroll(ScrollEventArgs se)
        {
            base.OnScroll(se);
            Invalidate();
        }
    }
1
9 / 9 / 5
Регистрация: 19.08.2016
Сообщений: 86
21.08.2016, 12:34  [ТС]
Вот что получилось...
Миниатюры
Какой это контрол?  
0
9 / 9 / 5
Регистрация: 19.08.2016
Сообщений: 86
21.08.2016, 12:44  [ТС]
Как теперь сделать правое поле для редактирования и повешать либо Chekbox, Combobox, Richtextbox ?
0
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
21.08.2016, 12:54
Генерируем контролы для редактирования значений, добавляем некторые вспомогательные методы:

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
    /// <summary>
    /// Грид для редактирования одной строки таблицы
    /// </summary>
    public class RowDataGrid : UserControl
    {
        private const int RowHeight = 30;
        private const int LeftColumnWidth = 200;
 
        private DataRow dataRow;
        public DataRow DataRow
        {
            get { return dataRow; }
            set { dataRow = value; Build(); }
        }
 
        private List<DataColumn> columns = new List<DataColumn>();
 
        public RowDataGrid()
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.ResizeRedraw, true);
        }
 
        private void Build()
        {
            //получаем все столбцы таблицы
            columns = DataRow.Table.Columns.OfType<DataColumn>().ToList();
            //считаем внутренний размер контрола
            AutoScrollMinSize = new Size(0, RowHeight*(columns.Count + 1));
        }
 
        protected override void OnPaint(PaintEventArgs e)
        {
            if (columns == null || DataRow == null)
                return;
 
            var gr = e.Graphics;
 
            //смещаем канву в соотв со скроллом
            gr.TranslateTransform(0, -VerticalScroll.Value);
 
            //рисуем грид
            for(int i=0;i<columns.Count + 2;i++)
            {
                var y = i*RowHeight;
                gr.DrawLine(Pens.Silver, 0, y, ClientSize.Width, y);
            }
 
            //верт линия
            gr.DrawLine(Pens.Silver, LeftColumnWidth, 0, LeftColumnWidth, RowHeight * (columns.Count + 1));
 
            //
            var sf = StringFormat.GenericTypographic;
 
            //рисуем название полей и значения
            sf = StringFormat.GenericTypographic;
            sf.LineAlignment = StringAlignment.Center;
 
            for (int i = 0; i < columns.Count; i++)
            {
                var y = RowHeight*(i + 1);
                //поле
                sf.Alignment = StringAlignment.Far;
                var rect = new Rectangle(0, y, LeftColumnWidth, RowHeight);
                rect.Inflate(-4, -2);
                gr.DrawString(columns[i].ColumnName, Font, Brushes.Navy, rect, sf);
 
                //значение
                sf.Alignment = StringAlignment.Near;
                rect = new Rectangle(LeftColumnWidth, y, ClientSize.Width - LeftColumnWidth, RowHeight);
                rect.Inflate(-4, -2);
                var val = dataRow[i] ?? "";
                gr.DrawString(val.ToString(), Font, Brushes.Black, rect, sf);
            }
 
            //рисуем шапку
            gr.ResetTransform();
            using (var brush = new LinearGradientBrush(new Rectangle(0, 0, 10, RowHeight), Color.Gainsboro, Color.Silver, 90))
            {
                sf.Alignment = sf.LineAlignment = StringAlignment.Center;
 
                var rect = new Rectangle(0, 0, LeftColumnWidth, RowHeight);
                gr.FillRectangle(brush, rect);
                gr.DrawString("Поле", Font, Brushes.Black, rect, sf);
 
                rect = new Rectangle(LeftColumnWidth, 0, ClientSize.Width - LeftColumnWidth, RowHeight);
                gr.FillRectangle(brush, rect);
                gr.DrawString("Значение", Font, Brushes.Black, rect, sf);
            }
        }
 
        protected override void OnScroll(ScrollEventArgs se)
        {
            base.OnScroll(se);
            Invalidate();
        }
 
        //контрол для редактирования значения
        private Control EditControl;
 
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
 
            if (EditControl != null)
            {
                EditControl.Dispose();
            }
 
            //индекс колонки, куда кликнули
            var index = PointToIndex(e.Location);
            if (index < 0)
                return;
 
            //создаем контрол для редактирования значения
            BuildEditControl(index);
        }
 
        private void BuildEditControl(int index)
        {
            //создаем контрол в соответствии с типом колонки
            EditControl = null;
            switch(columns[index].DataType.Name)
            {
                case "Bool": EditControl = CreateCheckBox(index); break;
                default: EditControl = CreateTextBox(index); break;
            }
 
            //активируем контрол после создания
            EditControl.HandleCreated += delegate { ActiveControl = EditControl; };
 
            var rect = GetRectangle(index);
            EditControl.Bounds = rect;
            EditControl.Parent = this;
        }
 
        private Control CreateTextBox(int index)
        {
            var ctrl = new TextBox();
            ctrl.Text = dataRow[index].ToString();
            ctrl.TextChanged += delegate { dataRow[index] = ctrl.Text; };
            ctrl.KeyDown += (o, e) => { if (e.KeyData == Keys.Enter) ctrl.Dispose();};
            return ctrl;
        }
 
        private Control CreateCheckBox(int index)
        {
            var ctrl = new CheckBox();
            ctrl.Checked = bool.Parse(dataRow[index].ToString());
            ctrl.CheckedChanged += delegate { dataRow[index] = ctrl.Checked; };
            return ctrl;
        }
 
        /// <summary>
        /// Возвращает номер колонки по координатам точки
        /// </summary>
        int PointToIndex(Point p)
        {
            var index = (p.Y + VerticalScroll.Value) / RowHeight - 1;
            return index >= columns.Count ? -1 : index;
        }
 
        /// <summary>
        /// Возвращает прямоугольник, содержащий значение для данного и номера колонки
        /// </summary>
        Rectangle GetRectangle(int index)
        {
            var y = RowHeight * (index + 1) - VerticalScroll.Value;
            var rect = new Rectangle(LeftColumnWidth, y, ClientSize.Width - LeftColumnWidth, RowHeight);
            rect.Inflate(-4, -2);
            return rect;
        }
    }
1
Эксперт .NETАвтор FAQ
 Аватар для Storm23
10427 / 5157 / 1825
Регистрация: 11.01.2015
Сообщений: 6,226
Записей в блоге: 34
21.08.2016, 13:09
Лучший ответ Сообщение было отмечено KSTMK как решение

Решение

Исправляем некоторые ошибки. Помимо TextBox и CheckBox, добавляем DateTimePicker.
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
    /// <summary>
    /// Грид для редактирования одной строки таблицы
    /// </summary>
    public class RowDataGrid : UserControl
    {
        private const int RowHeight = 30;
        private const int LeftColumnWidth = 200;
 
        private DataRow dataRow;
        public DataRow DataRow
        {
            get { return dataRow; }
            set { dataRow = value; Build(); }
        }
 
        private List<DataColumn> columns = new List<DataColumn>();
 
        public RowDataGrid()
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.UserPaint | ControlStyles.ResizeRedraw, true);
        }
 
        private void Build()
        {
            //получаем все столбцы таблицы
            columns = DataRow.Table.Columns.OfType<DataColumn>().ToList();
            //считаем внутренний размер контрола
            AutoScrollMinSize = new Size(0, RowHeight*(columns.Count + 1));
        }
 
        protected override void OnPaint(PaintEventArgs e)
        {
            if (columns == null || DataRow == null)
                return;
 
            var gr = e.Graphics;
 
            //смещаем канву в соотв со скроллом
            gr.TranslateTransform(0, -VerticalScroll.Value);
 
            //рисуем грид
            for(int i=0;i<columns.Count + 2;i++)
            {
                var y = i*RowHeight;
                gr.DrawLine(Pens.Silver, 0, y, ClientSize.Width, y);
            }
 
            //верт линия
            gr.DrawLine(Pens.Silver, LeftColumnWidth, 0, LeftColumnWidth, RowHeight * (columns.Count + 1));
 
            //
            var sf = StringFormat.GenericTypographic;
 
            //рисуем название полей и значения
            sf = StringFormat.GenericTypographic;
            sf.LineAlignment = StringAlignment.Center;
 
            for (int i = 0; i < columns.Count; i++)
            {
                var y = RowHeight*(i + 1);
                //поле
                sf.Alignment = StringAlignment.Far;
                var rect = new Rectangle(0, y, LeftColumnWidth, RowHeight);
                rect.Inflate(-4, -2);
                gr.DrawString(columns[i].ColumnName, Font, Brushes.Navy, rect, sf);
 
                //значение
                sf.Alignment = StringAlignment.Near;
                rect = new Rectangle(LeftColumnWidth, y, ClientSize.Width - LeftColumnWidth, RowHeight);
                rect.Inflate(-4, -2);
                var val = dataRow[i] ?? "";
                gr.DrawString(val.ToString(), Font, Brushes.Black, rect, sf);
            }
 
            //рисуем шапку
            gr.ResetTransform();
            using (var brush = new LinearGradientBrush(new Rectangle(0, 0, 10, RowHeight), Color.Gainsboro, Color.Silver, 90))
            {
                sf.Alignment = sf.LineAlignment = StringAlignment.Center;
 
                var rect = new Rectangle(0, 0, LeftColumnWidth, RowHeight);
                gr.FillRectangle(brush, rect);
                gr.DrawString("Поле", Font, Brushes.Black, rect, sf);
 
                rect = new Rectangle(LeftColumnWidth, 0, ClientSize.Width - LeftColumnWidth, RowHeight);
                gr.FillRectangle(brush, rect);
                gr.DrawString("Значение", Font, Brushes.Black, rect, sf);
            }
        }
 
        protected override void OnScroll(ScrollEventArgs se)
        {
            base.OnScroll(se);
            Invalidate();
        }
 
        //контрол для редактирования значения
        private Control EditControl;
 
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
 
            if (EditControl != null)
            {
                EditControl.Dispose();
            }
 
            //индекс колонки, куда кликнули
            var index = PointToIndex(e.Location);
            if (index < 0)
                return;
 
            //создаем контрол для редактирования значения
            BuildEditControl(index);
        }
 
        private void BuildEditControl(int index)
        {
            //создаем контрол в соответствии с типом колонки
            EditControl = null;
            switch(columns[index].DataType.Name)
            {
                case "Boolean": EditControl = CreateCheckBox(index); break;
                case "DateTime": EditControl = CreateDateTime(index); break;
                default: EditControl = CreateTextBox(index); break;
            }
 
            //активируем контрол после создания
            EditControl.HandleCreated += delegate { ActiveControl = EditControl; };
            EditControl.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right;
 
            var rect = GetRectangle(index);
            EditControl.Bounds = rect;
            EditControl.Parent = this;
        }
 
        private Control CreateDateTime(int index)
        {
            var ctrl = new DateTimePicker();
            ctrl.Format = DateTimePickerFormat.Short;
            ctrl.Value = (DateTime)dataRow[index];
            ctrl.ValueChanged += delegate { dataRow[index] = ctrl.Value; };
            return ctrl;
        }
 
        private Control CreateTextBox(int index)
        {
            var ctrl = new TextBox();
            ctrl.Text = dataRow[index].ToString();
            ctrl.TextChanged += delegate { dataRow[index] = ctrl.Text; };
            ctrl.KeyDown += (o, e) => { if (e.KeyData == Keys.Enter) ctrl.Dispose();};
            return ctrl;
        }
 
        private Control CreateCheckBox(int index)
        {
            var ctrl = new CheckBox();
            ctrl.Checked = bool.Parse(dataRow[index].ToString());
            ctrl.CheckedChanged += delegate { dataRow[index] = ctrl.Checked; };
            return ctrl;
        }
 
        /// <summary>
        /// Возвращает номер колонки по координатам точки
        /// </summary>
        int PointToIndex(Point p)
        {
            var index = (p.Y + VerticalScroll.Value) / RowHeight - 1;
            return index >= columns.Count ? -1 : index;
        }
 
        /// <summary>
        /// Возвращает прямоугольник, содержащий значение для данного и номера колонки
        /// </summary>
        Rectangle GetRectangle(int index)
        {
            var y = RowHeight * (index + 1) - VerticalScroll.Value;
            var rect = new Rectangle(LeftColumnWidth, y, ClientSize.Width - LeftColumnWidth, RowHeight);
            rect.Inflate(-4, -2);
            return rect;
        }
 
        protected override void OnMouseWheel(MouseEventArgs e)
        {
            base.OnMouseWheel(e);
            Invalidate();
        }
    }


Все, базовый компонент готов. ComboBox, RichTextBox и т.д. добавляем аналогично, на свой вкус.
Итого управились за 1 час 30 минут.
6
9 / 9 / 5
Регистрация: 19.08.2016
Сообщений: 86
21.08.2016, 13:18  [ТС]
Спасибо огромное...!!! Очень помогли!!! Побольше таких добрых и отзывчивых людей !
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
21.08.2016, 13:18
Помогаю со студенческими работами здесь

Какой это шаблон проектирования, и можно ли сделать в C# также (как в С++)?
Добрый день. Когда я сталкивался ранее с наследованием классов и полиморфизмом, то это было или, 1) дописывание каких то новых...

Что это за контрол?
В отладочных инструментах студии есть замечательный контрол - таблица/дерво со сверткой строк: Что это вообще за контрол?

Что это за контрол
Здравствуйте! Видел его в играх некоторых. Обычно он статичный, в углу экрана. Используется для управления. Как джойстик. Водишь по...

Подскажите, что это за контрол
Возник вопрос, что это за контрол? Думал, что dataGridView, однако нет.

Какой контрол выбрать?
Здравствуйте! Подскажите пожалуйста какой контрол выбрать? Хочу расположить дивы по такому принципу: https://www.pinterest.com, то есть...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru