Click here to Skip to main content
15,886,067 members
Articles / Programming Languages / Visual Basic

RestrictedUI: A .NET Library for restricting a user interface based on a security policy

Rate me:
Please Sign up or sign in to vote.
4.30/5 (17 votes)
26 May 2010MPL21 min read 26.8K   1.3K   69  
How to control the user interface using a policy established in a declaratively way, based on user roles and application status.
Option Strict On

' RestrictedUI: MOZILLA PUBLIC LICENSE STATEMENT.
' -----------------------------------------------------------
' The contents of this file are subject to the Mozilla Public
' License Version 1.1 (the "License"); you may not use this file
' except in compliance with the License. You may obtain a copy of
' the License at http://www.mozilla.org/MPL/

' Software distributed under the License is distributed on an "AS
' IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
' implied. See the License for the specific language governing
' rights and limitations under the License.

' The Original Code is RestrictedUI 1.0.

' The Initial Developer of the Original Code is Daniel Prado Velasco
' <dpradov@gmail.com> (Spain).
' Portions created by Daniel Prado Velasco are
' Copyright (C) 2010. All Rights Reserved.
' -----------------------------------------------------------
' Contributor(s):
' -----------------------------------------------------------
' History:
' -----------------------------------------------------------
' Released: 13 April 2010
' -----------------------------------------------------------
' URLs:
'  http://code.google.com/p/restricted-ui/


''' <summary>
''' It provides a treatment in the row selection of DataGridView objects (with checkbox) similar to that provided in Gmail contacts:
''' The column with the checkbox control will be marked by selecting the row.
''' You may click the checkbox column itself without losing the added marks so far, either by row selection or by clicking in that 
''' checkbox column
''' </summary>
''' <remarks></remarks>
Public Class GridSelectionMng
    Private _cGrid As DataGridView
    Private _cbSelectAll As CheckBox
    Private _colIndex As Integer

    Sub New(ByVal dataGrid As DataGridView, ByVal colIndex As Integer, Optional ByVal checkboxAll As CheckBox = Nothing)
        If dataGrid Is Nothing Then Exit Sub

        _cGrid = dataGrid
        _cbSelectAll = checkboxAll
        _colIndex = colIndex

        AddHandler _cGrid.CellClick, AddressOf cGrid_CellClick
        AddHandler _cGrid.SelectionChanged, AddressOf cGrid_SelectionChanged
        AddHandler _cGrid.CellValueChanged, AddressOf cGrid_CellValueChanged
        AddHandler _cGrid.CurrentCellDirtyStateChanged, AddressOf cGrid_CurrentCellDirtyStateChanged
        AddHandler _cGrid.CellPainting, AddressOf cGrid_CellPainting

        If _cbSelectAll IsNot Nothing Then
            AddHandler _cbSelectAll.Click, AddressOf cbSelectAll_Click
        End If
    End Sub

    Protected Overrides Sub Finalize()
        MyBase.Finalize()

        If _cGrid IsNot Nothing Then
            RemoveHandler _cGrid.CellClick, AddressOf cGrid_CellClick
            RemoveHandler _cGrid.SelectionChanged, AddressOf cGrid_SelectionChanged
            RemoveHandler _cGrid.CellValueChanged, AddressOf cGrid_CellValueChanged
            RemoveHandler _cGrid.CurrentCellDirtyStateChanged, AddressOf cGrid_CurrentCellDirtyStateChanged
            RemoveHandler _cGrid.CellPainting, AddressOf cGrid_CellPainting
        End If
        If _cbSelectAll IsNot Nothing Then
            RemoveHandler _cbSelectAll.Click, AddressOf cbSelectAll_Click
        End If
    End Sub

    Public Property ColorCheckedRow() As Brush
        Get
            Return _colorCheckedRow
        End Get
        Set(ByVal value As Brush)
            _colorCheckedRow = value
        End Set
    End Property
    Private _colorCheckedRow As Brush = Brushes.LightSalmon

    ''' <summary>It forces selected rows to be checked and highlighted</summary>
    ''' <param name="uncheckNotSelected">If it's <b>true</b> then it will be highlighted only those that are currently selected, 
    ''' the rest that could have the check but are not selected will uncheck. 
    ''' If it is <b>false</b> those selected will be added to the already marked
    ''' </param>
    ''' <remarks>
    ''' We offer this method because the row selection makes rows being marked, therefore highlighting the latter,
    ''' only when the focus is on control.
    ''' </remarks>
    Public Sub CheckSelectedRows(ByVal uncheckNotSelected As Boolean)
        If uncheckNotSelected Then
            CheckOnlySelectedRows()
        Else
            CheckSelectedRows()
        End If
        VerifyExistenceRowsChecked()
    End Sub

    Private Sub cGrid_CellClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs)
        If My.Computer.Keyboard.ShiftKeyDown Then Exit Sub ' If Shift pressed -> Exit because it will already be managed from SelectionChanged

        If e.ColumnIndex <> 0 Then
            If Not (My.Computer.Keyboard.CtrlKeyDown Or My.Computer.Keyboard.ShiftKeyDown) Then
                CheckOnlySelectedRows()
            Else
                _cGrid.Rows(e.RowIndex).Cells(_colIndex).Value = Not CType(_cGrid.Rows(e.RowIndex).Cells(_colIndex).Value, Boolean)
                _cGrid.InvalidateRow(e.RowIndex)
            End If
        End If
        VerifyExistenceRowsChecked()
    End Sub

    Private Sub cGrid_SelectionChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        If _cGrid.Focused Then
            If Control.MouseButtons = Windows.Forms.MouseButtons.Left Then
                If My.Computer.Keyboard.ShiftKeyDown Then
                    CheckSelectedRows() ' Shift+Left Click -> We add selected rows to those already marked
                End If

            ElseIf Control.MouseButtons = Windows.Forms.MouseButtons.None Then
                If Not (My.Computer.Keyboard.CtrlKeyDown Or My.Computer.Keyboard.ShiftKeyDown) Then
                    CheckOnlySelectedRows()  ' Selection changed, mouse not used, and Shift and Control not pressed -> mark only those that are selected
                Else
                    CheckSelectedRows()  ' Only keyboard. Shift or Control pressed -> We add selected rows to those already marked
                End If
            End If
        End If
        VerifyExistenceRowsChecked()
    End Sub

    Private Sub cGrid_CellValueChanged(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs)
        If e.ColumnIndex = 0 Then
            _cGrid.InvalidateRow(e.RowIndex)
            VerifyExistenceRowsChecked()
        End If
    End Sub

    Private Sub cGrid_CurrentCellDirtyStateChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
        If _cGrid.CurrentCell.ColumnIndex <> 0 Or _cGrid.CurrentRow.IsNewRow Then Exit Sub
        If _cGrid.IsCurrentCellDirty Then
            _cGrid.CommitEdit(DataGridViewDataErrorContexts.Commit)
        End If

    End Sub

    Private Sub cGrid_CellPainting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs)
        If e.RowIndex < 0 Then Exit Sub
        If _cGrid.Focused And _cGrid.CurrentCell IsNot Nothing AndAlso (Not _cGrid.CurrentCell.ReadOnly And _cGrid.Rows(e.RowIndex).Cells(e.ColumnIndex) Is _cGrid.CurrentCell) Then
            e.PaintBackground(e.CellBounds, True)

        ElseIf CType(_cGrid.Rows(e.RowIndex).Cells(_colIndex).Value, Boolean) Then
            Dim gridBrush As New SolidBrush(_cGrid.GridColor)
            Dim gridLinePen As New Pen(gridBrush)

            e.Graphics.FillRectangle(_colorCheckedRow, e.CellBounds)

            ' Draw the grid lines (only the right and bottom lines. DataGridView takes care of the others).
            e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, _
                e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, _
                e.CellBounds.Bottom - 1)
            e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1, _
                e.CellBounds.Top, e.CellBounds.Right - 1, _
                e.CellBounds.Bottom)
        Else
            e.PaintBackground(e.CellBounds, False)
        End If
        e.PaintContent(e.CellBounds)
        e.Handled = True
    End Sub

    Private Sub cbSelectAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        _cGrid.Invalidate()
    End Sub

    Private Function VerifyExistenceRowsChecked(Optional ByVal verifyDataBoundItem As Boolean = False) As Boolean
        Dim hayFilasMarcadas As Boolean = False
        For Each r As DataGridViewRow In _cGrid.Rows
            Try
                If verifyDataBoundItem Then
                    If r.DataBoundItem Is Nothing Then Continue For
                End If
                If CType(r.Cells(_colIndex).Value, Boolean) Then
                    hayFilasMarcadas = True
                    Exit For
                End If
            Catch ex As Exception
            End Try
        Next
        If _cbSelectAll IsNot Nothing Then
            _cbSelectAll.Checked = hayFilasMarcadas
        End If
        Return hayFilasMarcadas
    End Function

    Private Sub CheckSelectedRows()
        If _cGrid.SelectionMode = DataGridViewSelectionMode.FullRowSelect Then
            For Each r As DataGridViewRow In _cGrid.SelectedRows
                r.Cells(_colIndex).Value = True
            Next

        Else
            For Each c As DataGridViewCell In _cGrid.SelectedCells
                _cGrid.Rows(c.RowIndex).Cells(_colIndex).Value = True
            Next
        End If

    End Sub

    Private Sub CheckOnlySelectedRows()
        If _cGrid.SelectionMode = DataGridViewSelectionMode.FullRowSelect Then
            For Each r As DataGridViewRow In _cGrid.Rows
                If CType(r.Cells(_colIndex).Value, Boolean) <> r.Selected Then
                    r.Cells(_colIndex).Value = r.Selected
                End If
            Next

        Else
            Dim selected As Boolean
            For Each r As DataGridViewRow In _cGrid.Rows
                If r.IsNewRow Then Continue For
                selected = False
                For Each c As DataGridViewCell In r.Cells
                    If _cGrid.SelectedCells.Contains(c) Then
                        selected = True
                        Exit For
                    End If
                Next
                r.Cells(_colIndex).Value = selected
            Next
        End If

    End Sub

End Class

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Mozilla Public License 1.1 (MPL 1.1)


Written By
Spain Spain
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions