2012年6月28日 星期四

在 WinForm 的 DataGridView 中將Button設置為 Disable


  • 使用情境

有許多情況我們必須根本不同條件來控制是否啟用每一行 DataGridView 的按鈕,而不是將整列按鈕隱藏
例如依權限開放按鈕給使用者,若無權限則將該行按鈕關閉或隱藏


這件事在 ASP.NET 中的實作是輕而易舉,但在 WinForm 中卻找不到 DataGridViewButtonCell 有  Enabled 的屬性來控制按鈕的啟用狀態
##CONTINUE##

  • 實作方法

故為達此目的,必須透過繼承 DataGridViewButtonCell 來建立 User Control的方式來擴充功能
程式碼如下

Public Class DataGridViewDisableButtonCell
    Inherits DataGridViewButtonCell
    Private enabledValue As Boolean

    Public Property Enabled() As Boolean
        Get
            Return enabledValue
        End Get
        Set(value As Boolean)
            enabledValue = value
        End Set
    End Property

    Public Overrides Function Clone() As Object
        Dim cell As DataGridViewDisableButtonCell = DirectCast(MyBase.Clone(), DataGridViewDisableButtonCell)
        cell.Enabled = Me.Enabled
        Return cell
    End Function

    Public Sub New()
        Me.enabledValue = True
    End Sub

    Protected Overrides Sub Paint(graphics As Graphics, clipBounds As Rectangle, cellBounds As Rectangle, rowIndex As Integer, elementState As DataGridViewElementStates, value As Object, _
     formattedValue As Object, errorText As String, cellStyle As DataGridViewCellStyle, advancedBorderStyle As DataGridViewAdvancedBorderStyle, paintParts As DataGridViewPaintParts)

        If Not Me.enabledValue Then
            If (paintParts And DataGridViewPaintParts.Background) = DataGridViewPaintParts.Background Then
                Dim cellBackground As New SolidBrush(cellStyle.BackColor)
                graphics.FillRectangle(cellBackground, cellBounds)
                cellBackground.Dispose()
            End If

            If (paintParts And DataGridViewPaintParts.Border) = DataGridViewPaintParts.Border Then
                PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle)
            End If

            Dim buttonArea As Rectangle = cellBounds
            Dim buttonAdjustment As Rectangle = Me.BorderWidths(advancedBorderStyle)
            buttonArea.X += buttonAdjustment.X
            buttonArea.Y += buttonAdjustment.Y
            buttonArea.Height -= buttonAdjustment.Height
            buttonArea.Width -= buttonAdjustment.Width
            ButtonRenderer.DrawButton(graphics, buttonArea, VisualStyles.PushButtonState.Disabled)

            If TypeOf Me.FormattedValue Is [String] Then
                TextRenderer.DrawText(graphics, DirectCast(Me.FormattedValue, String), Me.DataGridView.Font, buttonArea, SystemColors.GrayText)
            End If
        Else
            MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, elementState, value, _
             formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts)
        End If
    End Sub
End Class

重建專案後,在新增 DataGridView 的欄位時就可看到剛剛建立的 DataGridViewDisableButtonCell


控制 Button Enabled 狀態通常是在 DataBind 之後,故攔截 DataBindingComplete 事件,將判斷實作於此

例如
        For Each oRow As DataGridViewRow In gvProjectFlow.Rows

            '依權限開啟 button
            Dim iFlowID As Integer = Integer.Parse(oRow.Cells("FlowID").Value)
            Dim oProjectFlowEntity As Entity.ProjectFlow = oProjectFlowBll.GetEntity(sProjectNumber, iFlowID)
            Dim oButtonCell As DataGridViewDisableButtonCell = CType(oRow.Cells("Excute"), DataGridViewDisableButtonCell)

            If oProjectFlowEntity.AssigneeUserName = UserSession.UserName And oProjectFlowEntity.State = Common.ProjectStateEnum.Incomplete Then
                oButtonCell.Enabled = True
            Else
                oButtonCell.Enabled = False
            End If
        Next





沒有留言:

張貼留言