1 / 1 / 0
Регистрация: 02.05.2017
Сообщений: 12
1

CheckBox в DataGridView

21.07.2017, 09:02. Показов 5472. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток. Делаю программу для подсчета голосов.

Что имеем:
Есть некая таблица datagridview1, которая состоит из, к примеру, 44 строк. В ней хранится информация о собственниках (в том числе ФИО и номер квартиры). На этой же форме есть таблица golos (которая тоже datagridview). В этой таблице пользователем вручную будет отмечено, кто и как проголосовал. Соответственно, эта таблица состоит из n столбцов, где n - количество рассмотренных на голосовании вопросов (вводится пользователем) и m строк, где m = кол-во строк в datagridview1 * 3 (по три варианта голосования для каждого собственника: за, против и воздержался).

Задача:
Все ячейки в таблице должны быть типа CheckBox. Казалось бы, все просто, но таблица создается полностью программно, а возможность менять программно тип ячейки я найти не могу. Максимум, что у меня получилось, на скриншоте. Дальше моск и гугл отказываются работать =(
В идеале, конечно, красиво было бы сделать еще одну колонку в начале, которая будет содержать слова ЗА, ПРОТИВ, ВОЗДЕРЖАЛСЯ, и так циклично для каждого собственника, однако как это сделать, я тоже пока не особо понимаю.
Прошу вашей помощи, уважаемые знатоки.
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
           golos.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
            int cc= Convert.ToInt32(textBox2.Text); //кол-во вопросов
 
            for (int i=0; i<cc; i++)
            {
                DataGridViewCheckBoxColumn col = new DataGridViewCheckBoxColumn();
                col.HeaderText = "Вопрос " + (i+1);
                golos.Columns.Add(col);
            }
 
            golos.RowHeadersWidth = 200;
            golos.RowCount = dataGridView1.RowCount * 3;
      
 
            int k = 0;
            for (int i = 0; i < golos.Rows.Count-1; i+=3)
            {
                golos.Rows[i].HeaderCell.Value= dataGridView1.Rows[k].Cells[2].Value.ToString()+"\n" 
+ dataGridView1.Rows[k].Cells[1].Value.ToString(); //заголовок-номер квартиры и ФИО
                k++;
            }
 
            golos.Visible = true;
        }
Миниатюры
CheckBox в DataGridView  
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.07.2017, 09:02
Ответы с готовыми решениями:

CheckBox в DataGridView отслеживание помеченых строк
Доброго времени суток! Имеется форма с DataGridView в нее загружаются данные из БД Есть столбец...

CheckBox в DataGridView
Привет всем. Есть некоторый вопрос: Есть DataGridView, в нем есть один столбец типом данных -...

DataGridView с CheckBox
Есть Datatable c типом: DataColumn(&quot;Check&quot;, typeof (bool)); Хочу когда выбиралось поле, у...

dataGridView + checkBox
добрый день! подскажите, как мне в таблицу dataGridView, заполняемую динамически, добавить checkBox...

9
0 / 0 / 0
Регистрация: 19.07.2017
Сообщений: 5
21.07.2017, 09:50 2
извините,что не по теме, но близко.
Diamanda, как вы вывели наименования ФИО и порядковый номер в самый первый столбец ? пришлите кусочек кода пожалуйста. Он обычно пустой при создании датагрида
0
910 / 795 / 329
Регистрация: 08.02.2014
Сообщений: 2,391
21.07.2017, 10:01 3
Diamanda, у меня для Вас два вида решения:
1) Добавляете перед вопросами ещё колонку с комбобоксом который и будет содержать Ваши за, против, воздержался и отталкиваетесь от этого уже
2) Пишите свою реализацию CheckBoxColumn чтобы она содержала не 1, а 3 чекбокса сразу с подписями
0
1 / 1 / 0
Регистрация: 02.05.2017
Сообщений: 12
21.07.2017, 10:13  [ТС] 4
red_biker,
C#
1
2
3
4
5
6
7
 int k = 0;
            for (int i = 0; i < golos.Rows.Count-1; i+=3)
            {
                golos.Rows[i].HeaderCell.Value= dataGridView1.Rows[k].Cells[2].Value.ToString()+"\n" 
+ dataGridView1.Rows[k].Cells[1].Value.ToString(); //заголовок-номер квартиры и ФИО
                k++;
            }
Добавлено через 2 минуты
SeIZVeIZ, с комбобоксом не получится, т.к. слишком много телодвижений придется пользователю совершать. Специально заказчик попросил именно такое оформление.
А насчет второго... не знаю, как это сделать, если честно. Я множко нуб в программировании
1
910 / 795 / 329
Регистрация: 08.02.2014
Сообщений: 2,391
21.07.2017, 10:22 5
Diamanda, думаю это Вам поможет, там радиобаттоны конечно, но в множественном выборе для Вас это даже лучше будет
1
910 / 795 / 329
Регистрация: 08.02.2014
Сообщений: 2,391
21.07.2017, 10:35 6
Лучший ответ Сообщение было отмечено Diamanda как решение

Решение

Ну и сам проект оттуда
Вложения
Тип файла: zip DataGridViewRadioButton.zip (37.2 Кб, 41 просмотров)
0
1 / 1 / 0
Регистрация: 02.05.2017
Сообщений: 12
21.07.2017, 15:04  [ТС] 7
SeIZVeIZ, спасибо, буду в понедельник разбираться =)
блин, радиобаттоны... совсем из головы они у меня вылетели, действительно, намного логичнее их использовать
0
8936 / 4848 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
22.07.2017, 01:27 8
Ячейка твоя должна содержать одно из слов «Да», «Нет» или «Воздержался». Это достаточно наглядно.
Начать с того, что нужен тип для хранения этих значений. Проще всего enum. Значения, отображаемые в dgv, задаём атрибутом DescriptionAttribute:
VotingResultEnum.cs
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System.ComponentModel;
 
namespace System.Windows.Forms
{
    /// <summary>
    /// Результат голосования
    /// </summary>
    [TypeConverter(typeof(VotingResultEnumConverter))]
    public enum VotingResultEnum
    {
        [Description("Да")]
        Yes,
        [Description("Нет")]
        No,
        [Description("Воздержался")]
        Abstain
    }
}

Чтобы эти значения правильно отображались в dgv, используем конвертер, заданный через атрибут TypeConverterAttribute:
VotingResultEnumConverter
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
using System.ComponentModel;
using System.Globalization;
 
namespace System.Windows.Forms
{
    internal class VotingResultEnumConverter : EnumConverter
    {
        public VotingResultEnumConverter(Type type) : base(type)
        {
        }
 
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(string))
            {
                var vr = (VotingResultEnum)value;
                return GetAttribute<DescriptionAttribute>(vr).Description;
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }
 
        internal static T GetAttribute<T>(Enum enumVal) where T : Attribute
        {
            var type = enumVal.GetType();
            var memInfo = type.GetMember(enumVal.ToString());
            var attributes = memInfo[0].GetCustomAttributes(typeof(T), false);
            return attributes.Length > 0 ? (T)attributes[0] : null;
        }
    }
}


Но для редактирования значения ячейки нужно использовать свой контрол с тремя вариантами выбора:
VoteSelector.cs
Название: 2017-07-22_010002.png
Просмотров: 328

Размер: 2.3 Кб
Каждая кнопка — это RadioButton с Appearance = Button
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
namespace System.Windows.Forms
{
    /// <summary>
    /// Контрол для выбора результат голосования
    /// </summary>
    public partial class VoteSelector : UserControl
    {
        private VotingResultEnum _voteResult;
        public event EventHandler VoteResultChanged;
        /// <summary>
        /// Результат голосования
        /// </summary>
        public VotingResultEnum VoteResult
        {
            get { return _voteResult; }
            set
            {
                if (_voteResult == value) return;
                _voteResult = value;
                OnVoteResultChanged();
                UpdateView();
            }
        }
 
        private void UpdateView()
        {
            switch (_voteResult)
            {
                case VotingResultEnum.Yes:
                    yesRadioButton.Checked = true;
                    break;
                case VotingResultEnum.No:
                    noRadioButton.Checked = true;
                    break;
                case VotingResultEnum.Abstain:
                    abstainRadioButton.Checked = true;
                    break;
            }
        }
 
        protected virtual void OnVoteResultChanged()
        {
            VoteResultChanged?.Invoke(this, EventArgs.Empty);
        }
 
        public VoteSelector()
        {
            InitializeComponent();
            yesRadioButton.Tag = VotingResultEnum.Yes;
            noRadioButton.Tag = VotingResultEnum.No;
            abstainRadioButton.Tag = VotingResultEnum.Abstain;
            UpdateView();
        }
 
        private void radioButton_CheckedChanged(object sender, EventArgs e)
        {
            var rb = sender as RadioButton;
            if (!rb.Checked) return;
            VoteResult = (VotingResultEnum)rb.Tag;
        }
    }
}

Чтобы редактировать значение с помощью этого контрола, нужно реализовать интерфейс IDataGridViewEditingControl:
VotingEditCell.cs
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
namespace System.Windows.Forms
{
    /// <summary>
    /// Контрол для редактирования значения в ячейке
    /// </summary>
    public class VotingEditCell : VoteSelector, IDataGridViewEditingControl
    {
        #region Реализация IDataGridViewEditingControl
 
        public DataGridView EditingControlDataGridView { get; set; }
 
        public object EditingControlFormattedValue
        {
            get
            {
                return GetEditingControlFormattedValue(DataGridViewDataErrorContexts.Formatting);
            }
            set
            {
                if (value is VotingResultEnum)
                {
                    VoteResult = (VotingResultEnum)value;
                }
                else if (value is string)
                {
                    VoteResult = (VotingResultEnum)Enum.Parse(typeof(VotingResultEnum), value?.ToString());
                }
                else
                {
                    VoteResult = default(VotingResultEnum);
                }
            }
        }
 
        public int EditingControlRowIndex { get; set; }
        public bool EditingControlValueChanged { get; set; }
 
        public Cursor EditingPanelCursor
        {
            get { return base.Cursor; }
        }
 
        public bool RepositionEditingControlOnValueChange
        {
            get { return false; }
        }
 
        public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
        {
            return;
        }
 
        public bool EditingControlWantsInputKey(Keys keyData, bool dataGridViewWantsInputKey)
        {
            return !dataGridViewWantsInputKey;
        }
 
        public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
        {
            return VoteResult.ToString();
        }
 
        public void PrepareEditingControlForEdit(bool selectAll)
        {
            return;
        }
        #endregion
 
        protected override void OnVoteResultChanged()
        {
            EditingControlValueChanged = true;
            EditingControlDataGridView?.NotifyCurrentCellDirty(true);
            base.OnVoteResultChanged();
        }
    }
}

Затем необходима ячейка DGV, которой назначим редактором класс VotingEditCell. Поскольку отображаться будет просто текст, то наследуемся от DataGridViewTextBoxCell:
VotingCell
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
using System.ComponentModel;
using System.Drawing;
 
namespace System.Windows.Forms
{
    /// <summary>
    /// Ячейка для отображения результат голосования
    /// </summary>
    public class VotingCell : DataGridViewTextBoxCell
    {
        /// <summary>
        /// Редактор значения в ячейке
        /// </summary>
        public override Type EditType
        {
            get { return typeof(VotingEditCell); }
        }
        /// <summary>
        /// Тип значения в ячейке
        /// </summary>
        public override Type ValueType
        {
            get { return typeof(VotingResultEnum); }
        }
        /// <summary>
        /// Значение для новой строки по умолчанию
        /// </summary>
        public override object DefaultNewRowValue
        {
            get { return default(VotingResultEnum); }
        }
        /// <summary>
        /// Преобразование введённого значения
        /// </summary>
        public override object ParseFormattedValue(object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter)
        {
            if (formattedValue is VotingResultEnum)
            {
                return formattedValue;
            }
            else if (formattedValue is string)
            {
                return (VotingResultEnum)Enum.Parse(typeof(VotingResultEnum), formattedValue.ToString());
            }
            return base.ParseFormattedValue(formattedValue, cellStyle, formattedValueTypeConverter, valueTypeConverter);
        }
        /// <summary>
        /// Инициализация контрола редактирования ячейки
        /// </summary>
        public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
        {
            base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
            var ectl = DataGridView.EditingControl as VotingEditCell;
            if (ectl == null) return;
            ectl.VoteResult = Value != null
                ? (VotingResultEnum)Value
                : default(VotingResultEnum);
        }
        /// <summary>
        /// Положение и размер контрола для редактирования
        /// </summary>
        public override void PositionEditingControl(bool setLocation, bool setSize, Rectangle cellBounds, Rectangle cellClip, DataGridViewCellStyle cellStyle, bool singleVerticalBorderAdded, bool singleHorizontalBorderAdded, bool isFirstDisplayedColumn, bool isFirstDisplayedRow)
        {
            var size = DataGridView.EditingControl.Size;
            var rect = new Rectangle(cellBounds.Location, size);
            base.PositionEditingControl(setLocation, setSize, rect, rect, cellStyle, singleVerticalBorderAdded, singleHorizontalBorderAdded, isFirstDisplayedColumn, isFirstDisplayedRow);
        }
    }
}

И в конце концов, нужен столбец DGV, в который поместим VotingCell:
VotingColumn
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
namespace System.Windows.Forms
{
    /// <summary>
    /// Столбец с ячейкой результата голосования
    /// </summary>
    public class VotingColumn : DataGridViewTextBoxColumn
    {
        private VotingCell _cellTemplate;
 
        public override DataGridViewCell CellTemplate
        {
            get
            {
                if (_cellTemplate == null)
                    _cellTemplate = new VotingCell();
                return _cellTemplate;
            }
            set
            {
                _cellTemplate = (VotingCell)value;
            }
        }
    }
}


Теперь в dgv можно добавлять наш столбец хоть программно, хоть через редактор столбцов и задавать значения. В рантайме значение редактируется как обычно: двойной клик или F2
Во вложении два проекта: библиотека с контролами и приложение WinForms для демонстрации
Вложения
Тип файла: zip VotingForms.zip (19.8 Кб, 16 просмотров)
2
1 / 1 / 0
Регистрация: 02.05.2017
Сообщений: 12
24.07.2017, 05:02  [ТС] 9
SeIZVeIZ, больше спасибо! Разобраться мозгов мне не хватило, а вот подключить уже готовый класс и создать на его основе свое - всегда пожалуйста, нас этому в технаре научили =))
Миниатюры
CheckBox в DataGridView  
0
1 / 1 / 0
Регистрация: 02.05.2017
Сообщений: 12
27.07.2017, 05:41  [ТС] 10
Проблема этого класса в том, что при попытке получить значение ячейки через Value он возвращает null, т.к. после выбора одного из вариантов ответа редактирование ячейки не завершается. Поэтому получать значение ячейки нужно через EditedFormattedValue.

Ну, может, кому-то понадобится в будущем.
0
27.07.2017, 05:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.07.2017, 05:41
Помогаю со студенческими работами здесь

Работа с checkbox в datagridview
Здравствуйте! Столкнулся с такой проблемой. Имеется TreeView, по нажатию на ветку которого...

Связать CheckBox с DataGridView
Всем здравствуйте! Есть dataGridView уже связанный с сервером SQL и ниже есть куча СheckBox'ов...

CheckBox & DataGridView
Добрый день. Подскажите, пожалуйста. Не получается реализовать CheckBox &amp; DataGridView. Таблица...

checkbox в заголовке datagridview
Салют еще раз. Имею datagridview в header которого тыркаю checkbox, он вставляется но в левый...

DataGridView и CheckBox в ее ячейках
Имеется следующий код: string strSQL; string strConn; strSQL = &quot;SELECT One, Two, Three, Four,...

DataGridView: CheckBox столбец
В DataGridView данные у меня считываются через DataSource = List&lt;MyClass&gt; с включенным...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru