(NET) NET (2013)

Set HandCursor for all ToolStripButton by Linq, Extension, Delegates, Lambda Expression and Anonymous Action.



1. Extension function with Linq.

This is very simple future, but for write similar code free, need to deep understanding all Visual Basic opportunity. Firstly, this is two simple extension function to obtain all control by type or name.


 110:      <Extension()>
 111:      Public Function FindRecusriveByName(ByVal control As Control, ControlName As String) As IEnumerable(Of Control)
 112:          Dim controls = control.Controls.Cast(Of Control)()
 113:          Return controls.SelectMany(Function(ctrl) FindRecusriveByName(ctrl, ControlName)).Concat(controls).Where(Function(c) c.Name = ControlName)
 114:      End Function
 115:   
 116:      <Extension()>
 117:      Public Function FindRecusriveByType(ByVal control As Control, ByVal type As Type) As IEnumerable(Of Control)
 118:          Dim controls = control.Controls.Cast(Of Control)()
 119:          Return controls.SelectMany(Function(ctrl) FindRecusriveByType(ctrl, type)).Concat(controls).Where(Function(c) c.[GetType]() = type)
 120:      End Function
 121:   
 122:   
 123:  End Module

I use they in different rules, for example set a custom format of DatagridView.



But code below is more sophisticated and interesting, because it use one Lambda expression including to another.


2. Use Lambda Expression to call Delegates in ForEach by AddressOF statement.

In the internal part I call EventHandler delegates ToolStripButton_MouseEnter and ToolStripButton_MouseLeave by keyword AddressOF. More details about delegates (Static/Dynamic declaration, AddressOf/RaiseEvent/AddHandler/WithEvents/Handles statement, SingleCast/MultiCast/InvocationList, Invoke/BeginInvoke/DynamicInvoke/AsyncInvoke, Automatically instantiate) please see in this my article - Events/Delegates in VB.NET



  41:      Dim savedCursor As Windows.Forms.Cursor
  42:   
  43:      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
  44:   
  45:          Me.FindRecusriveByType(GetType(ToolStrip)).ToList.ForEach(Sub(Y)
  46:                                                                        Dim ToolStrip = CType(Y, ToolStrip)
  47:                                                                        ToolStrip.Items.OfType(Of ToolStripButton).ToList.ForEach(Sub(X)
  48:                                                                                                                                      Debug.Print(X.Name)
  49:                                                                                                                                      AddHandler X.MouseEnter, AddressOf ToolStripButton_MouseEnter
  50:                                                                                                                                      AddHandler X.MouseLeave, AddressOf ToolStripButton_MouseLeave
  51:                                                                                                                                  End Sub)
  52:                                                                    End Sub)
  53:          Me.FindRecusriveByType(GetType(StatusStrip)).ToList.ForEach(Sub(Y)
  54:                                                                          Dim ToolStrip = CType(Y, StatusStrip)
  55:                                                                          ToolStrip.Items.OfType(Of ToolStripButton).ToList.ForEach(Sub(X)
  56:                                                                                                                                        Debug.Print(X.Name)
  57:                                                                                                                                        AddHandler X.MouseEnter, AddressOf ToolStripButton_MouseEnter
  58:                                                                                                                                        AddHandler X.MouseLeave, AddressOf ToolStripButton_MouseLeave
  59:                                                                                                                                    End Sub)
  60:                                                                      End Sub)
  ...   
  76:      Private Sub ToolStripButton_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs)
  77:          If savedCursor Is Nothing Then
  78:              savedCursor = Me.Cursor
  79:              Me.Cursor = Cursors.Hand
  80:          End If
  81:      End Sub
  82:   
  83:      Private Sub ToolStripButton_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs)
  84:          Me.Cursor = savedCursor
  85:          savedCursor = Nothing
  86:      End Sub
  87:   

3. Use one Named function as Action to different type of controls for call delegates.

And this is next step to simplify code, it use characteristic of StatusStrip class, because it inherit from ToolStrip, we can use one Action to both type on container.



Pay attention than both of syntax (45 and 46 line) is equal.


  41:      Dim savedCursor As Windows.Forms.Cursor
  42:   
  43:      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
  44:   
  45:          Me.FindRecusriveByType(GetType(ToolStrip)).ToList.ForEach(New Action(Of Control)(AddressOf SetCursor))
  46:          Me.FindRecusriveByType(GetType(StatusStrip)).ToList.ForEach(AddressOf SetCursor)
  ...   
  63:      Sub SetCursor(Y)
  64:          Dim ToolStrip = CType(Y, ToolStrip)
  65:          ToolStrip.Items.OfType(Of ToolStripButton).ToList.ForEach(Sub(X)
  66:                                                                        Debug.Print(X.Name)
  67:                                                                        AddHandler X.MouseEnter, AddressOf ToolStripButton_MouseEnter
  68:                                                                        AddHandler X.MouseLeave, AddressOf ToolStripButton_MouseLeave
  69:                                                                    End Sub)
  70:      End Sub
  71:   

4. Use Anonymous Action instead named function.

And finally you can see my last version of implementation the same future with anonymous Action (one of both type).


  41:      Dim savedCursor As Windows.Forms.Cursor
  42:   
  43:      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
  44:   
  45:          Me.FindRecusriveByType(GetType(ToolStrip)).ToList.ForEach(SetCursor)
  46:          Me.FindRecusriveByType(GetType(StatusStrip)).ToList.ForEach(SetCursor)
  47:   
  ...   
  63:      Dim SetCursor As Action(Of Control) = Sub(Y As Control)
  64:                                                Dim ToolStrip = CType(Y, ToolStrip)
  65:                                                ToolStrip.Items.OfType(Of ToolStripButton).ToList.ForEach(Sub(X)
  66:                                                                                                              Debug.Print(X.Name)
  67:                                                                                                              AddHandler X.MouseEnter, AddressOf ToolStripButton_MouseEnter
  68:                                                                                                              AddHandler X.MouseLeave, AddressOf ToolStripButton_MouseLeave
  69:                                                                                                          End Sub)
  70:                                            End Sub


Comments ( )
Link to this page: //www.vb-net.com/HandCursor/Index.htm
< THANKS ME>