【问题标题】:Is it possible to populate a DataGridViewComboBoxCell with a custom ComboBox?是否可以使用自定义 ComboBox 填充 DataGridViewComboBoxCell?
【发布时间】:2020-01-07 09:21:39
【问题描述】:

我目前正在编写一个遵循一些特定设计规则的程序。为此,我创建了一个自定义 ComboBox 类,它实现了边框和自定义下拉按钮。

我在主视图中也有一个 DataGridView,它有一个 DataGridViewComboBoxColumn。不幸的是,那些组合框不遵循设计规则。是否可以修改 DataGridViewComboBoxCell 类以使其使用我的自定义 ComboBox 类?不幸的是,到目前为止还没有在网上找到任何东西。


我的 ComboBox 类

public class FlatCombo : ComboBox {
        private const int WM_PAINT = 0xF;
        private int buttonWidth = SystemInformation.HorizontalScrollBarArrowWidth;

        public Color BorderColor { get; set; }
        public Color CircleColor { get; set; }
        public Color ButtonColor { get; set; }

        public FlatCombo() {
            BorderColor = C1;
            CircleColor = C2;
            ButtonColor = C1;
            base.BackColor = C2;
        }

        protected override void WndProc(ref Message m) {
            base.WndProc(ref m);
            if (m.Msg == WM_PAINT) {
                //Draw outlines
                using (var g = Graphics.FromHwnd(Handle)) {
                    using (var p = new Pen(BorderColor)) {
                        //Draw outlines of the dropdown menu
                        g.DrawRectangle(p, 0, 0, Width - 1, Height - 1);
                        g.DrawLine(p, Width - buttonWidth - 1, 0, Width - buttonWidth - 1, Height);
                    }
                    using (var bb = new SolidBrush(ButtonColor)) {
                        //Draw background of the dropdown button
                        g.FillRectangle(bb, Width - 17, 1, 16, Height - 2);
                    }
                    using (var cb = new SolidBrush(CircleColor)) {
                        //Draw circle of the dropdown button
                        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                        g.FillEllipse(cb, Width - 12, (Height - 6) / 2, 5, 5);
                    }
                }
            }
        }
    }

【问题讨论】:

  • 是的,我想是的。但是您需要遵循here 中概述的托管自定义单元类型的规则。相当多的工作。
  • 额外的工作问题不大。我真的不知道在哪里定义用于创建 DataGridViewCell 的类以及要覆盖的类等。
  • 你必须研究链接。
  • 您添加的不是DataGridViewComboBoxCell,而是您的DataGridViewMyComboBoxCell。我会尝试挖掘DataGridViewProgressCell 我在某个地方并发布在下面

标签: c# datagridview customization datagridviewcombobox datagridviewcomboboxcell


【解决方案1】:

这是DataGridViewProgressColumn 的示例类,基本上应该正是您想要实现的目标:

Imports System.Drawing
Imports System.ComponentModel
Public Class DataGridViewProgressColumn
    Inherits DataGridViewImageColumn
    Public Sub New()
        Me.CellTemplate = New DataGridViewProgressCell
    End Sub
End Class
Public Class DataGridViewProgressCell
    Inherits DataGridViewImageCell

    Sub New()
        ValueType = Type.GetType("Integer")
    End Sub
    ' Method required to make the Progress Cell consistent with the default Image Cell. 
    ' The default Image Cell assumes an Image as a value, although the value of the Progress Cell is an Integer.
    Protected Overrides Function GetFormattedValue( _
        ByVal value As Object, _
        ByVal rowIndex As Integer, _
        ByRef cellStyle As DataGridViewCellStyle, _
        ByVal valueTypeConverter As TypeConverter, _
        ByVal formattedValueTypeConverter As TypeConverter, _
        ByVal context As DataGridViewDataErrorContexts _
        ) As Object
        Static emptyImage As Bitmap = New Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
        GetFormattedValue = emptyImage
    End Function

    Protected Overrides Sub Paint(ByVal g As System.Drawing.Graphics, ByVal clipBounds As System.Drawing.Rectangle, ByVal cellBounds As System.Drawing.Rectangle, ByVal rowIndex As Integer, ByVal cellState As System.Windows.Forms.DataGridViewElementStates, ByVal value As Object, ByVal formattedValue As Object, ByVal errorText As String, ByVal cellStyle As System.Windows.Forms.DataGridViewCellStyle, ByVal advancedBorderStyle As System.Windows.Forms.DataGridViewAdvancedBorderStyle, ByVal paintParts As System.Windows.Forms.DataGridViewPaintParts)
        Try

            Dim progressVal As Integer = CType(IIf(IsDBNull(value), 0, value), Integer)
            Dim percentage As Single = CType((progressVal / 100), Single)
            Dim backBrush As Brush = New SolidBrush(cellStyle.BackColor)
            Dim foreBrush As Brush = New SolidBrush(cellStyle.ForeColor)
            ' Call the base class method to paint the default cell appearance.
            MyBase.Paint(g, clipBounds, cellBounds, rowIndex, cellState, _
                value, formattedValue, errorText, cellStyle, _
                advancedBorderStyle, paintParts)
            If percentage > 0.0 Then
                ' Draw the progress bar and the text
                g.FillRectangle(New SolidBrush(Color.FromArgb(163, 189, 242)), cellBounds.X + 2, cellBounds.Y + 2, Convert.ToInt32((percentage * cellBounds.Width - 4)), cellBounds.Height - 4)
                g.DrawString(progressVal.ToString() & "%", cellStyle.Font, foreBrush, cellBounds.X + 6, cellBounds.Y + 2)
            Else
                'draw the text
                If Not Me.DataGridView.CurrentCell Is Nothing AndAlso Me.DataGridView.CurrentCell.RowIndex = rowIndex Then
                    g.DrawString(progressVal.ToString() & "%", cellStyle.Font, New SolidBrush(cellStyle.SelectionForeColor), cellBounds.X + 6, cellBounds.Y + 2)
                Else
                    g.DrawString(progressVal.ToString() & "%", cellStyle.Font, foreBrush, cellBounds.X + 6, cellBounds.Y + 2)
                End If
            End If
        Catch ex As Exception
            MsgBox("Graf nemohl být načten.")
        End Try
    End Sub
End Class

定义您的 Columns 并将它们添加到 DataGridView(您也可以在 GUI 中执行此操作!):

Dim WIcol0 As New DataGridViewTextBoxColumn
Dim WIcol1 As New DataGridViewTextBoxColumn
Dim WIcol2 As New DataGridViewTextBoxColumn
Dim WIcol3 As New DataGridViewTextBoxColumn
Dim WIcol4 As New DataGridViewTextBoxColumn
Dim WIcol4a As New DataGridViewProgressColumn   ' <<< Define a column of your type

            With WIcol0
                .Width = "45"
                .HeaderText = "#"
                .DataPropertyName = "RowNo"
                .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft
                .DefaultCellStyle.Padding = New Padding(6, 0, 0, 0)
                .Name = .DataPropertyName
                .Visible = True
                .ReadOnly = True
            End With
            With WIcol1
                .Width = "250"
                .HeaderText = "Company Name"
                .DataPropertyName = "CompanyName"
                .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft
                .DefaultCellStyle.Padding = New Padding(6, 0, 0, 0)
                .Name = .DataPropertyName
                .Visible = True
                .ReadOnly = True
            End With
            With WIcol2
                .Width = "100"
                .HeaderText = "Turnover"
                .DataPropertyName = "Turnover"
                .DefaultCellStyle.Format = "# ### ##0.00 Kč"
                .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
                .Name = .DataPropertyName
                .ReadOnly = True
            End With
            With WIcol3
                .Width = "80"
                .HeaderText = "Running Time"
                .DataPropertyName = "RunningTime"
                .DefaultCellStyle.Format = "0 dní"
                '.DefaultCellStyle.Padding = New Padding(6, 0, 0, 0)
                .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
                .Name = .DataPropertyName
                .ReadOnly = True
            End With
            With WIcol4
                .Width = "80"
                .HeaderText = "After"
                .DataPropertyName = "After"
                .DefaultCellStyle.Format = "0.0 dní"
                .DefaultCellStyle.Font = New Font(Me.dgwOTD.Font, FontStyle.Bold)
                .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
                .Name = .DataPropertyName
                .ReadOnly = True
            End With
            With WIcol4a
                .Width = "80"
                .HeaderText = "Performance"
                .DataPropertyName = "Performance"
                '.DefaultCellStyle.Format = "0 dní"
                .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
                .DefaultCellStyle.ForeColor = Color.LightGray
                .Name = .DataPropertyName
                .DefaultCellStyle.Format = ""
                .ReadOnly = True
            End With    

编辑:我刚刚意识到它是 VB.NET 并且你有 C#,但逻辑当然是相同的。如果您阅读有困难,请发表评论,我会附上翻译后的 C# 代码。

【讨论】:

    猜你喜欢
    • 2021-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 2013-04-08
    相关资源
    最近更新 更多