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

Контекстное меню для DataGridView: как работать с группой ячеек

28.11.2012, 13:43. Показов 7045. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток!
На заморском сайте надыбал код для добавления и использования контекстного меню в гриде, только вот работать можно только с одной ячейкой(копировать, вырезать и тд),как же распространить этот код на несколько ячеек, например выделить три ячейки в колонке одного грида и вставить в выделенные ячейки другого грида или другой колонки тогоже грида? Вот код:

1. При загрузке формы:
VB.NET
1
2
3
4
5
6
7
8
9
10
 Dim _contextmenu As New ContextMenuStrip
        _contextmenu.Items.Add("Cut")
        _contextmenu.Items.Add("Copy")
        _contextmenu.Items.Add("Paste")
        AddHandler _contextmenu.ItemClicked, AddressOf contextmenu_click
        For Each rw As DataGridViewRow In DataGridView1.Rows
            For Each c As DataGridViewCell In rw.Cells
                c.ContextMenuStrip = _contextmenu
            Next
        Next
2. Затем фиксирование на выделенной ячейке(я так понял):
VB.NET
1
2
3
4
5
6
7
8
9
10
Private Sub DataGridView1_CellMouseDown(ByVal sender As System.Object, _
                     ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) _
                     Handles DataGridView1.CellMouseDown
        If e.RowIndex <> -1 And e.ColumnIndex <> -1 Then
            If e.Button = MouseButtons.Right Then
                Dim clickCell As DataGridViewCell = sender.Rows(e.RowIndex).Cells(e.ColumnIndex)
                clickCell.Selected = True
            End If
        End If
    End Sub
3. И в конце действия при выборе того или иного пункта:
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Private Sub contextmenu_click(ByVal sender As System.Object, _
                                  ByVal e As ToolStripItemClickedEventArgs)
        Dim clickCell As DataGridViewCell = DataGridView1.SelectedCells(0)
        Select Case e.ClickedItem.Text
            Case "Cut"
                Clipboard.SetText(clickCell.Value)
                clickCell.Value = ""
            Case "Copy"
                Clipboard.SetText(clickCell.Value, TextDataFormat.Text)
 
            Case "Paste"
                clickCell.Value = Clipboard.GetText(TextDataFormat.Text)
        End Select
    End Sub
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.11.2012, 13:43
Ответы с готовыми решениями:

Контекстное меню для DataGridView, как лучше сделать?
Привет друзья, всех с наступающим Новым Годом, всех Благ. Пишу для себя программу, и хочу...

Как вызвать контекстное меню по конкретной записи в DataGridView?
делаю так: Private Sub DataGridView1_MouseDown(sender As Object, e As MouseEventArgs) Handles...

Как создать контекстное меню. Например нажимая на richTextBox правой кнопкой мыши, мне бы предоставлялось контекстное меню
Как создать контекстное меню. Например нажимая на richTextBox правой кнопкой мыши, мне бы...

Как создать контекстное меню при нажатии правой кнопкой мыши по DataGridView
Создать то я создала, но для того чтоб открылось меню сначала надо щелкнуть по ячейке левой кнопкой...

10
35 / 35 / 1
Регистрация: 14.11.2012
Сообщений: 176
28.11.2012, 23:05 2
можно копировать не только TextDataFormat.Text, а все выделенные ячейки как текст разделенный табом
при вставке, если в буфере есть табы, делить текст по ним и вставлять в ячейки подряд
0
0 / 0 / 0
Регистрация: 16.11.2012
Сообщений: 62
30.11.2012, 10:18  [ТС] 3
Ух спасибо! А можно пример в коде?Очень уж хочется реализовать такую приблуду!

Добавлено через 5 часов 29 минут
Выяснил что ещё необходимо выставить параметр Multiline=True, для выделения нескольких ячеек, но по прежнему не знаю как поместить в буфер данные из всех выделенных ячеек а не из последней из выделенных?

Добавлено через 21 час 13 минут
Народ, вы убиваете молчанием!
Чуть разобрался с копированием нескольких ячеек:
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
Private Sub contextmenu_click(ByVal sender As System.Object, ByVal e As ToolStripItemClickedEventArgs)
        If Me.DataGridView1.GetCellCount(DataGridViewElementStates.Selected) > 0 Then
            Try
                Select Case e.ClickedItem.Text
                    Case "Копировать"
                        Clipboard.SetDataObject(Me.DataGridView1.GetClipboardContent())
                End Select
            Catch ex As Exception
 
            End Try
        End If
    End Sub
теперь не-пойму как реализовать вставку скопированного в другие ячейки и очистку выделенных ячеек?
0
35 / 35 / 1
Регистрация: 14.11.2012
Сообщений: 176
30.11.2012, 10:57 4
в txt получаешь текст всех выделенных ячеек (разделенные табом - ячейки в строке и переводом строки - строки)
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
Dim i, n, k, r As Integer, txt As String
        r = -1
        For i = 0 To DataGridView1.SelectedCells.Count - 1
            n = DataGridView1.SelectedCells(0).ColumnIndex
            k = DataGridView1.SelectedCells(0).RowIndex
            If r < k Then
                If i > 0 Then txt = txt & vbNewLine
            Else
                txt = txt & vbTab
            End If
            txt = txt & DataGridView1.Item(n, k).Value.ToString
        Next
Потом txt используешь вместо clickCell.Value
VB.NET
1
2
Case "Copy"
                Clipboard.SetText(txt, TextDataFormat.Text)
Получаешь из буфера
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
Dim tr(), tc() As String
        txt = Clipboard.GetText(TextDataFormat.Text)
        If InStr(txt, vbNewLine) > 0 Or InStr(txt, vbTab) > 0 Then 'если есть Tab или Перевод строки - делаем разбор
            n = DataGridView1.CurrentCell.ColumnIndex
            k = DataGridView1.CurrentCell.RowIndex
            tr = txt.Split(vbNewLine)
            For r = 0 To tr.Length - 1
                tc = tr(r).Split(vbTab)
                For i = 0 To tc.Length - 1
                    DataGridView1.Item(n + i, k + r).Value = tc(i) 'присваиваем ячейке текст соответствующего фрагмента
                Next
            Next
        End If
0
0 / 0 / 0
Регистрация: 16.11.2012
Сообщений: 62
30.11.2012, 13:07  [ТС] 5
Спасибо за отзыв!У меня кроме числовых значений в ячейках ещё и текстовые имеются, а здесь копируются только числовые и вместо текста табуляторы ставятся и если вставлять например 4 скопированных ячейки в 4 соседних то почемуто происходит сдвиг на несколько ячеек вниз и в последние добавляются табы. Вот скрин:
Контекстное меню для DataGridView: как работать с группой ячеек
0
35 / 35 / 1
Регистрация: 14.11.2012
Сообщений: 176
30.11.2012, 15:27 6
ну вы даете. Вам дают пример, а вы его даже не хотите посмотреть и обработать, естественно в нем есть ошибки, т.к. написан с листа и не проверялся.
Итак, на форме только DataGridView1. Вот рабочий код
VB.NET
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
Public Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim tb As New DataTable, wr As DataRow, i As Integer
 
        tb.Columns.Add("Txt", Type.GetType("System.String"))
        tb.Columns.Add("dt", Type.GetType("System.DateTime"))
        tb.Columns.Add("Num", Type.GetType("System.Double"))
        tb.Columns.Add("Txt2", Type.GetType("System.String"))
        tb.Columns.Add("dt2", Type.GetType("System.DateTime"))
        tb.Columns.Add("Num2", Type.GetType("System.Double"))
 
        For i = 0 To 9
            wr = tb.NewRow
            wr("Txt") = "r" & i
            wr("dt") = Date.Today.AddDays(-i)
            wr("Num") = i * 10
            wr("Txt2") = "dodo" & i
            wr("dt2") = Date.Today.AddMonths(-i)
            wr("Num2") = (i + 88) * 2
            tb.Rows.Add(wr)
        Next
        DataGridView1.DataSource = tb
 
        Dim _contextmenu As New ContextMenuStrip
        _contextmenu.Items.Add("Cut")
        _contextmenu.Items.Add("Copy")
        _contextmenu.Items.Add("Paste")
        AddHandler _contextmenu.ItemClicked, AddressOf contextmenu_click
        For Each rw As DataGridViewRow In DataGridView1.Rows
            For Each c As DataGridViewCell In rw.Cells
                c.ContextMenuStrip = _contextmenu
            Next
        Next
    End Sub
    Private Sub DataGridView1_CellMouseDown(ByVal sender As System.Object, _
                     ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) _
                     Handles DataGridView1.CellMouseDown
        If e.RowIndex <> -1 And e.ColumnIndex <> -1 Then
            If e.Button = MouseButtons.Right Then
                Dim clickCell As DataGridViewCell = sender.Rows(e.RowIndex).Cells(e.ColumnIndex)
                clickCell.Selected = True
            End If
        End If
    End Sub
    Private Sub contextmenu_click(ByVal sender As System.Object, _
                                  ByVal e As ToolStripItemClickedEventArgs)
        Dim clickCell As DataGridViewCell = DataGridView1.SelectedCells(0)
        Dim i, n, k, r, s As Integer, txt As String
        Select Case e.ClickedItem.Text
            Case "Cut"
                Clipboard.SetText(clickCell.Value)
                clickCell.Value = ""
            Case "Copy"
                r = -1
                s = DataGridView1.SelectedCells.Count - 1
                txt = ""
                For i = 0 To s
                    n = DataGridView1.SelectedCells(s - i).ColumnIndex
                    k = DataGridView1.SelectedCells(s - i).RowIndex
                    If r <> k Then
                        If i > 0 Then txt = txt & vbNewLine
                    Else
                        txt = txt & vbTab
                    End If
                    r = k
                    txt = txt & DataGridView1.Item(n, k).Value.ToString
                Next
                Clipboard.SetText(txt, TextDataFormat.Text)
                IO.File.WriteAllText("C:\txt.txt", txt)
            Case "Paste"
                Dim tr(), tc() As String
                txt = Clipboard.GetText(TextDataFormat.Text)
                If InStr(txt, vbNewLine) > 0 Or InStr(txt, vbTab) > 0 Then 'если есть Tab или Перевод строки - делаем разбор
                    n = DataGridView1.CurrentCell.ColumnIndex
                    k = DataGridView1.CurrentCell.RowIndex
                    txt = Replace(txt, vbNewLine, Chr(10))
                    tr = txt.Split(Chr(10))
                    For r = 0 To tr.Length - 1
                        tc = tr(r).Split(vbTab)
                        For i = 0 To tc.Length - 1
                            DataGridView1.Item(n + i, k + r).Value = tc(i) 'присваиваем ячейке текст соответствующего фрагмента
                        Next
                    Next
                End If
                'clickCell.Value = Clipboard.GetText(TextDataFormat.Text)
        End Select
    End Sub
 
End Class
Добавлено через 1 минуту
строку 69 можно убрать, это для проверки

Добавлено через 2 минуты
этот код для копирования/вставки нескольких ячеек, для одной добавьте свой код
1
0 / 0 / 0
Регистрация: 16.11.2012
Сообщений: 62
03.12.2012, 18:18  [ТС] 7
Отлично,спасибо, всё работает как надо и попеняли за дело!
0
0 / 0 / 0
Регистрация: 16.11.2012
Сообщений: 62
13.12.2012, 12:26  [ТС] 8
Flamberg, Подскажите, а если на этой же форме имеется второй DataGridView и необходимо копипастить между ними, как тогда проинициализировать и вторую табличку в Вашем коде? Думаю продублировать Ваш код с переименованием всех переменных и сменой DataGrid1 на DataGrid2 не приведёт к нужным результатам?
Вот собственно весь код формы с гридами:
VB.NET
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
Imports System.Xml
Imports System.Data
Public Class Form3
    Dim dt1 As New DataTable
    Dim dt2 As New DataTable
    Dim ds1 As New DataSet
    Dim ds2 As New DataSet
 
    Private Sub Form3_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 
        With Me
            .MaximizeBox = False
            Me.FormBorderStyle = Windows.Forms.FormBorderStyle.FixedSingle
            .StartPosition = FormStartPosition.CenterParent
            .Location = New Point(100, 300)
            .Text = "Таблица данных аутентификации"
            '.Label1.Text = "Рабочие ключи"
            '.Label1.Font = New Font("MS Sans Serif", 10.0!, FontStyle.Bold)
            '.Label1.ForeColor = Color.DarkGreen
            '.Label2.Text = "Старые ключи"
            '.Label2.Font = New Font("MS Sans Serif", 10.0!, FontStyle.Bold)
            '.Label2.ForeColor = Color.DarkGreen
            .GroupBox1.Text = "Генерация пароля"
            .GroupBox2.Text = "Рабочие ключи"
            .GroupBox3.Text = "Старые ключи"
            .GroupBox4.Text = ""
            .TextBox1.Text = ""
            .Button1.Text = "Сохранить"
            .Button2.Text = "Генерировать"
            .Button3.Text = "Выход"
            .Button5.Text = "Изменить"
            .DataGridView1.RowHeadersVisible = False
            .DataGridView2.RowHeadersVisible = False
            .DataGridView1.EditMode = DataGridViewEditMode.EditOnF2
            .DataGridView2.EditMode = DataGridViewEditMode.EditOnF2
            .DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
            .DataGridView2.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
            .DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText
            .DataGridView2.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText
        End With
 
 
        If IO.File.Exists("table\table1.xml") = False Then
            DataGridView1.DataSource = dt1
            dt1.Columns.Add("Наименование объекта")
            dt1.Columns.Add("Идентификатор")
            dt1.Columns.Add("Пароль")
            dt1.Columns.Add("Статус")
            dt1.Columns.Add("Дата установки")
            ds1.Tables.Add(dt1)
        Else
            ds1.ReadXml("table\table1.xml")
            DataGridView1.DataMember = "Рабочие ключи"
            DataGridView1.DataSource = ds1
        End If
 
        If IO.File.Exists("table\table2.xml") = False Then
            DataGridView2.DataSource = dt2
            dt2.Columns.Add("Идентификатор")
            dt2.Columns.Add("Пароль")
            dt2.Columns.Add("Статус")
            dt2.Columns.Add("Дата установки")
            ds2.Tables.Add(dt2)
        Else
            ds2.ReadXml("table\table2.xml")
            DataGridView2.DataMember = "Старые ключи"
            DataGridView2.DataSource = ds2
        End If
 
        Dim _contextmenu As New ContextMenuStrip
        _contextmenu.Items.Add("Вырезать")
        _contextmenu.Items.Add("Копировать")
        _contextmenu.Items.Add("Вставить")
        AddHandler _contextmenu.ItemClicked, AddressOf contextmenu_click
        For Each rw As DataGridViewRow In DataGridView1.Rows
            For Each c As DataGridViewCell In rw.Cells
                c.ContextMenuStrip = _contextmenu
            Next
        Next
    End Sub
 
    Private Sub DataGridView1_CellMouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseDown
        If e.RowIndex <> -1 And e.ColumnIndex <> -1 Then
            If e.Button = MouseButtons.Right Then
                Dim clickCell As DataGridViewCell = sender.Rows(e.RowIndex).Cells(e.ColumnIndex)
                clickCell.Selected = True
            End If
        End If
    End Sub
 
    Private Sub contextmenu_click(ByVal sender As System.Object, ByVal e As ToolStripItemClickedEventArgs)
        Dim clickCell As DataGridViewCell = DataGridView1.SelectedCells(0)
        Dim i, n, k, r, s As Integer, txt As String
        Try
            Select Case e.ClickedItem.Text
                Case "Вырезать"
                    Clipboard.SetText(clickCell.Value)
                    clickCell.Value = ""
                Case "Копировать"
                    r = -1
                    s = DataGridView1.SelectedCells.Count - 1
                    txt = ""
                    For i = 0 To s
                        n = DataGridView1.SelectedCells(s - i).ColumnIndex
                        k = DataGridView1.SelectedCells(s - i).RowIndex
                        If r <> k Then
                            If i > 0 Then txt = txt & vbNewLine
                        Else
                            txt = txt & vbTab
                        End If
                        r = k
                        txt = txt & DataGridView1.Item(n, k).Value.ToString
                    Next
                    Clipboard.SetText(txt, TextDataFormat.Text)
                    'IO.File.WriteAllText("C:\txt.txt", txt)
                Case "Вставить"
                    Dim tr(), tc() As String
                    txt = Clipboard.GetText(TextDataFormat.Text)
                    If InStr(txt, vbNewLine) > 0 Or InStr(txt, vbTab) > 0 Then 'если есть Tab или Перевод строки - делаем разбор
                        n = DataGridView1.CurrentCell.ColumnIndex
                        k = DataGridView1.CurrentCell.RowIndex
                        txt = Replace(txt, vbNewLine, Chr(10))
                        tr = txt.Split(Chr(10))
                        For r = 0 To tr.Length - 1
                            tc = tr(r).Split(vbTab)
                            For i = 0 To tc.Length - 1
                                DataGridView1.Item(n + i, k + r).Value = tc(i) 'присваиваем ячейке текст соответствующего фрагмента
                            Next
                        Next
                    End If
                    'clickCell.Value = Clipboard.GetText(TextDataFormat.Text)
            End Select
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
        End Try
 
    End Sub
 
    Public Function GenerateString(ByVal minLength As Integer, ByVal maxLength As Integer) As String
        Dim charset As String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        Dim r As New Random()
        Dim lenPass As Integer = r.Next(minLength, maxLength)
        Dim str As String = String.Empty
        For i As Integer = 0 To lenPass - 1
            str += charset(r.Next(0, charset.Length))
        Next
        Return str
    End Function
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        dt1.TableName = "Рабочие ключи"
        ds1.WriteXml("table\table1.xml")
        dt2.TableName = "Старые ключи"
        ds2.WriteXml("table\table2.xml")
        MessageBox.Show("Запись произведена")
    End Sub
 
    Private Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim pwd As String = GenerateString(8, 10)
        TextBox1.Text = (pwd)
    End Sub
 
    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Me.Close()
        Form1.WindowState = FormWindowState.Normal
    End Sub
0
35 / 35 / 1
Регистрация: 14.11.2012
Сообщений: 176
13.12.2012, 15:24 9
В самом начале процедуры contextmenu_click добавить
VB.NET
1
2
3
4
        Dim dtg As DataGridView
        If DataGridView1.Focused = True Then dtg = DataGridView1
        If DataGridView2.Focused = True Then dtg = DataGridView2
        If dtg Is Nothing Then Exit Sub
во всей данной процедуре DataGridView1 заменить на dtg
1
0 / 0 / 0
Регистрация: 16.11.2012
Сообщений: 62
14.12.2012, 10:49  [ТС] 10
Отлично, ещё добавил 2-ой цикл для DataGridView2 в контекстное меню
VB.NET
1
2
3
4
5
For Each rw1 As DataGridViewRow In DataGridView2.Rows
            For Each c1 As DataGridViewCell In rw1.Cells
                c1.ContextMenuStrip = _contextmenu
            Next
        Next
и в процедуру DataGridView1_CellMouseDown дописал
VB.NET
1
Handles DataGridView2.CellMouseDown
и всё заработало как необходимо, спасибо за помощь!
0
0 / 0 / 0
Регистрация: 28.04.2015
Сообщений: 2
15.01.2013, 14:15 11
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
Private Sub КопироватьToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles КопироватьToolStripMenuItem.Click
        Clipboard.Clear()
        Me.DataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableWithoutHeaderText
        Clipboard.SetDataObject(Me.DataGridView1.GetClipboardContent())
        Clipboard.GetData(DataFormats.Text)
        Dim dt As IDataObject = Clipboard.GetDataObject()
        If dt.GetDataPresent(GetType(String)) Then
            Dim tb As String = DirectCast((dt.GetData(GetType(String))), String)
            Dim encoding As System.Text.Encoding = System.Text.Encoding.GetEncoding(1251)
            Dim dataStr As Byte() = encoding.GetBytes(tb)
            Clipboard.SetDataObject(encoding.GetString(dataStr))
        End If
    End Sub
0
15.01.2013, 14:15
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.01.2013, 14:15
Помогаю со студенческими работами здесь

Контекстное меню DataGridView + выравнивание столбцов
Подскажите, как добавить контекстное меню для выбранной строки грида? и как выровнять колонки в...

Контекстное меню на dataGridView с множественным выбором
Всем привет, в сети ничего подобного не нашел. существует столбец с именами, хочу по нажатию пкм...

Как создать контекстное меню для QTableView ?
Есть QTableView. Надо что было по нажатия правой кнопкой мыши на ячейку таблицы был пункт меню...

Как создать контекстное меню для шейпа?
void __fastcall TForm1::Shape1ContextPopup(TObject *Sender, TPoint &amp;MousePos, bool &amp;Handled)...


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

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

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