Selecting Treeviewitem in WPF - wpf-controls

I have a search textbox to search the treeviewitem and select it. The child items in treeview are lazy loaded.
I want to select the child times of a treeview passed in search textbox.
how can i achieve this?
Thanks
Sharath

There's some good information about selecting items in a TreeView here:
http://askernest.com/archive/2008/01/23/how-to-programmatically-change-the-selecteditem-in-a-wpf-treeview.aspx
and here:
http://www.codeproject.com/KB/WPF/TreeView_SelectionWPF.aspx

Here is my helper, extract what you need:
PS. I never tested the ExpandAll method.
Imports System.Runtime.CompilerServices
Imports System.Windows.Controls.Primitives
<HideModuleName()>
Module TreeViewHelper
<Extension()>
Public Sub SetSelectedItem(ByVal treeView As TreeView, ByVal item As Object)
SetSelectedItemInternal(treeView, item)
End Sub
<Extension()>
Public Sub SetSelectedItem(ByVal treeViewItem As TreeViewItem,
ByVal item As Object)
SetSelectedItemInternal(treeViewItem, item)
End Sub
Private Sub SetSelectedItemInternal(ByVal control As ItemsControl,
ByVal item As Object)
ValidateItemsControl(control)
If item Is Nothing Then Throw New ArgumentNullException("item")
If Not control.Items.Contains(item) Then _
Throw New ArgumentOutOfRangeException("item",
"Specified item was not found in the control.")
If control.ItemContainerGenerator.Status =
GeneratorStatus.ContainersGenerated Then
DirectCast(control.ItemContainerGenerator.ContainerFromItem(item),
TreeViewItem).IsSelected = True
Else
Dim selectWhenReadyMethod As EventHandler
selectWhenReadyMethod =
Sub(sender, e)
If control.ItemContainerGenerator.Status =
GeneratorStatus.ContainersGenerated Then
RemoveHandler control.ItemContainerGenerator.StatusChanged,
selectWhenReadyMethod
SetSelectedItemInternal(control, item)
End If
End Sub
AddHandler control.ItemContainerGenerator.StatusChanged,
selectWhenReadyMethod
End If
End Sub
<Extension()>
Public Sub SetSelectedIndex(ByVal treeView As TreeView, ByVal index As Object)
SetSelectedIndexInternal(treeView, index)
End Sub
<Extension()>
Public Sub SetSelectedIndex(ByVal treeViewItem As TreeViewItem,
ByVal index As Object)
SetSelectedIndexInternal(treeViewItem, index)
End Sub
Private Sub SetSelectedIndexInternal(ByVal control As ItemsControl,
ByVal index As Object)
ValidateItemsControl(control)
If index < 0 OrElse index > control.Items.Count - 1 Then _
Throw New ArgumentOutOfRangeException("index")
If control.ItemContainerGenerator.Status =
GeneratorStatus.ContainersGenerated Then
DirectCast(control.ItemContainerGenerator.ContainerFromIndex(index),
TreeViewItem).IsSelected = True
Else
Dim selectWhenReadyMethod As EventHandler
selectWhenReadyMethod =
Sub(sender, e)
If control.ItemContainerGenerator.Status =
GeneratorStatus.ContainersGenerated Then
RemoveHandler control.ItemContainerGenerator.StatusChanged,
selectWhenReadyMethod
SetSelectedIndexInternal(control, index)
End If
End Sub
AddHandler control.ItemContainerGenerator.StatusChanged,
selectWhenReadyMethod
End If
End Sub
<Extension()>
Public Sub ExpandAll(ByVal treeView As TreeView)
ExpandAllInternal(treeView)
End Sub
<Extension()>
Public Sub ExpandAll(ByVal treeViewItem As TreeViewItem)
ExpandAllInternal(treeViewItem)
End Sub
Private Sub ExpandAllInternal(ByVal control As ItemsControl)
ValidateItemsControl(control)
If control.Items.IsEmpty Then Exit Sub
If control.ItemContainerGenerator.Status =
GeneratorStatus.ContainersGenerated Then
For i = 0 To control.Items.Count - 1
Dim item =
DirectCast(control.ItemContainerGenerator.ContainerFromIndex(i),
TreeViewItem)
item.IsExpanded = True
ExpandAllInternal(control)
Next
Else
Dim expandWhenReadyMethod As EventHandler
expandWhenReadyMethod =
Sub(sender, e)
If control.ItemContainerGenerator.Status =
GeneratorStatus.ContainersGenerated Then
RemoveHandler control.ItemContainerGenerator.StatusChanged,
expandWhenReadyMethod
ExpandAllInternal(control)
End If
End Sub
AddHandler control.ItemContainerGenerator.StatusChanged,
expandWhenReadyMethod
End If
End Sub
Private Sub ValidateItemsControl(ByVal control As ItemsControl)
If control Is Nothing Then Throw New ArgumentNullException("control")
If Not TypeOf control Is TreeView AndAlso
Not TypeOf control Is TreeViewItem Then _
Throw New _
NotSupportedException(control.GetType.FullName & " is not supported.")
End Sub
End Module

Related

Excel VBA UserForm Tag Property

I have a UserForm with Text and Combo Boxes, some of which represent "REQUIRED FIELDS" and cannot be left blank. I have entered the value RQD for the tag property of the target controls. My objective is to loop through the controls and use their Tag property to identify controls that cannot be empty (where Tag property value = RQD) and change their BackColor property if they are. However, I cannot get this work. Below is some of the code:-
With frm_RecCapture
'
.lbl01_RecDate = Format(Date, "Long Date", vbSunday)
.txt01_RecNum = Format(RecNum, "000000")
.txt01_RecNum.Enabled = False
.txt01_AccNum.SetFocus
'
frmComplete = False
.Show
'
Do While frmComplete = False
.Show
'
For Each frmCtrl In .Controls
If TypeName(frmCtrl) = "Textbox" Or TypeName(frmCtrl) = "Combobox" Then
If frmCtrl.Tag = "RQD" And frmCtrl.Text = "" Then
frmCtrl.BackColor = &HFFFF&
n = n + 1
End If
End If
Next frmCtrl
'
If n = 0 Then
frmComplete = True
Else
frmComplete = False
MsgBox "ERROR! Fields highlighted in yellow cannot be left blank. Please "
complete these fields before continuing.", vbInformation + vbOKOnly, SysTitle
End If
Loop
'
End With
Any suggestions? Thanks...
I prefer writing a class that wraps and validates a control. You will need to store a reference to the wrapper class in a collection of some type of class level variable keep it from falling out of scope.
Class: RequiredFieldControl
Option Explicit
Private WithEvents ComboBox As MSForms.ComboBox
Private WithEvents TextBox As MSForms.TextBox
Private mControl As MSForms.Control
Private Const DefaultBackColor As Long = -2147483643
Private Const InvalidBackColor As Long = vbYellow ' &HFFFF&
Public Property Set Control(ByVal Value As MSForms.Control)
Set mControl = Value
Select Case TypeName(Control)
Case "ComboBox"
Set ComboBox = Value
Case "TextBox"
Set TextBox = Value
End Select
FormatControl
End Property
Public Property Get Control() As MSForms.Control
Set Control = mControl
End Property
Sub FormatControl()
Control.BackColor = IIf(isValid, DefaultBackColor, InvalidBackColor)
End Sub
Public Function isValid() As Boolean
Select Case TypeName(Control)
Case "ComboBox"
isValid = ComboBox.ListIndex > -1
Case "TextBox"
isValid = Len(TextBox.Value) > 0
End Select
End Function
Private Sub ComboBox_Change()
FormatControl
End Sub
Private Sub TextBox_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
FormatControl
End Sub
Form Code
Private RequiredFields As Collection
Private Sub UserForm_Initialize()
Set RequiredFields = New Collection
AddRequiredFields Me.Controls
ComboBox1.List = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Debug.Print RequiredFields.Count
End Sub
Sub AddRequiredFields(pControls As MSForms.Controls)
Dim RequiredField As RequiredFieldControl
Dim Control As MSForms.Control
For Each Control In pControls
If Control.Tag = "RQD" Then
Select Case TypeName(Control)
Case "ComboBox", "TextBox"
Set RequiredField = New RequiredFieldControl
Set RequiredField.Control = Control
RequiredFields.Add RequiredField
End Select
Else
On Error Resume Next
AddRequiredFields Control.Controls
On Error GoTo 0
End If
Next
End Sub
Function AreAllRequiredFieldsFilled() As Boolean
Dim RequiredField As RequiredFieldControl
For Each RequiredField In RequiredFields
If Not RequiredField.isValid Then Exit Function
Next
AreAllRequiredFieldsFilled = True
End Function

Trying to add Textboxes to a userform dynamically?

I have code inside a excel workbook that helps me create mass emails to send to users of various programs. I have a userform that pops up and the user populates all the info needed. but that only counts for one app at a time. Can someone share code with me that dynamically adds textboxes to a userform dependant on what checkboxes are ticked ?
In the first frame I have check boxes that indicate what applications are affected, second frame I have option buttons to describe what type of incident and then I would like the textboxes to appear according to what has been ticked.
Any guidance much appreciated as I think this is way too deep for me at the moment
I've reverse engineered this code it adds the boxes I want but I need to be able to populate them with cell data and then use it in the emails:
Option Explicit
Dim SpnColct As Collection
Private Sub CommandButton2_Click()
Dim cSpnEvnt As cControlEvent
Dim ctlSB As Control
Dim ctlTXT As Control
Dim lngCounter As Long
For lngCounter = 1 To 7
Set ctlTXT = Me.Frame7.Controls.Add("Forms.TextBox.1", "Text" & lngCounter)
ctlTXT.Name = "Text" & lngCounter
ctlTXT.Left = 5
ctlTXT.Height = 125: ctlTXT.Width = 280
ctlTXT.Top = (lngCounter - 1) * 125 + 2
Set cSpnEvnt = New cControlEvent
Set cSpnEvnt.SP = ctlSB
Set cSpnEvnt.TXT = ctlTXT
SpnColct.Add cSpnEvnt
Next lngCounter
Me.Frame1.ScrollHeight = (lngCounter - 1) * 17 + 2
End Sub
This added to a class module:
Option Explicit
Public WithEvents SP As MSForms.SpinButton
Public WithEvents TXT As MSForms.TextBox
Private Sub SP_SpinDown()
SP.Value = SP.Value - 1
MsgBox "Spin Down to " & SP.Value
End Sub
Private Sub SP_SpinUp()
SP.Value = SP.Value + 1
MsgBox "Spin Up to " & SP.Value
End Sub
Private Sub TXT_Change()
MsgBox "You changed the value."
End Sub
Updated This is going to be a bit of a long one - step through it see if you understand it. Have changed it to create the textboxes on the CheckBox_Click event but change to the commandbutton if you wish. Any more then this and I think you'll need to start a new question.
I've been doing something similar recently and found that the reason you're having issues is due to the order of loading objects. I unfortunately can't find the link that explains it at the moment (will update if can) but briefly to be able to achieve this you need an additional Class that does the loading of the objects, otherwise the Userform can't see them. This is the kind of solution that I came up with (using your example)
Userform:
Option Explicit
Private WithEvents cControls As EventController
Private Sub cControls_Click(ctrl As CheckBoxControl)
Dim tBox As TextBoxControl
Dim i As Long
Dim NextTop As Long, FrameHeight As Long
For i = 1 To cControls.GetControls.Count
Debug.Print TypeName(cControls.GetControl(i))
If TypeName(cControls.GetControl(i)) = "TextBoxControl" Then
Set tBox = cControls.GetControl(i)
If tBox.TXT.Parent Is Me.Frame7 Then
NextTop = tBox.Top + tBox.Height
End If
End If
Next i
Set tBox = cControls.AddTextBox
With tBox
.Height = 125
.Width = 280
.Left = 5
.Top = NextTop
.TXT.Text = ctrl.cBox.Caption
FrameHeight = NextTop + .Height
End With
If FrameHeight > Me.Frame7.InsideHeight Then
With Me.Frame7
.ScrollBars = fmScrollBarsVertical
.ScrollHeight = FrameHeight
.Scroll yAction:=6
End With
End If
End Sub
Private Sub UserForm_Initialize()
Dim i As Long
Dim cBox As CheckBoxControl
Set cControls = New EventController
' This can be set to a userform or a frame
Set cControls.UserForm = Me
For i = 1 To 8
Set cBox = cControls.AddCheckBox
cBox.cBox.Left = 5
With cBox.cBox
.Top = 5 + (i - 1) * .Height
.Caption = IIf(i = 8, "App Unknown", "App " & i)
End With
Next i
End Sub
Private Sub cControls_Change(ctrl As TextBoxControl)
' This can be handled in the class instead as you were - just doing it in the userform to show the exposing of the event
MsgBox ctrl.TXT.Name & " Change"
End Sub
Private Sub cControls_SpinDown(ctrl As TextBoxControl)
' This can be handled in the class instead as you were - just doing it in the userform to show the exposing of the event
With ctrl.SP
If .Value >0 Then
.Value = .Value - 1
End If
End With
MsgBox ctrl.SP.Name & " Spin Down"
End Sub
Private Sub cControls_SpinUp(ctrl As TextBoxControl)
' This can be handled in the class instead as you were - just doing it in the userform to show the exposing of the event
With ctrl.SP
.Value = .Value + 1
End With
MsgBox ctrl.SP.Name & " Spin Up"
End Sub
Classes - These need to be named as in bold
EventControl
Option Explicit
Private CtrlCollection As Collection
Private cUserForm As UserForm1
Public Event SpinDown(ctrl As TextBoxControl)
Public Event SpinUp(ctrl As TextBoxControl)
Public Event Change(ctrl As TextBoxControl)
Public Event Click(ctrl As CheckBoxControl)
Public Property Set UserForm(v As UserForm1)
Set cUserForm = v
End Property
Public Property Get UserForm() As UserForm1
Set UserForm = cUserForm
End Property
Public Function AddTextBox() As TextBoxControl
Dim tBox As TextBoxControl
Set tBox = New TextBoxControl
tBox.Initialize Me
CtrlCollection.Add tBox
Set AddTextBox = tBox
End Function
Public Function AddCheckBox() As CheckBoxControl
Dim cBox As New CheckBoxControl
cBox.Initalize Me
CtrlCollection.Add cBox
Set AddCheckBox = cBox
End Function
Public Function GetControl(Index As Long)
Set GetControl = CtrlCollection(Index)
End Function
Public Function GetControls() As Collection
Set GetControls = CtrlCollection
End Function
Private Sub Class_Initialize()
Set CtrlCollection = New Collection
End Sub
Public Sub SpinDown(ctrl As TextBoxControl)
RaiseEvent SpinDown(ctrl)
End Sub
Public Sub SpinUp(ctrl As TextBoxControl)
RaiseEvent SpinUp(ctrl)
End Sub
Public Sub Change(ctrl As TextBoxControl)
RaiseEvent Change(ctrl)
End Sub
Public Sub Click(ctrl As CheckBoxControl)
RaiseEvent Click(ctrl)
End Sub
CheckBoxControl
Option Explicit
Public WithEvents cBox As MSForms.CheckBox
Private cParent As EventController
Public Property Set Parent(v As EventController)
Set cParent = v
End Property
Public Property Get Parent() As EventController
Set Parent = cParent
End Property
Public Sub Initalize(Parent As EventController)
Set Me.Parent = Parent
Set cBox = Parent.UserForm.Frame1.Controls.Add("Forms.CheckBox.1")
End Sub
Private Sub cBox_Click()
Parent.Click Me
End Sub
TextBoxControl
Option Explicit
Public WithEvents SP As MSForms.SpinButton
Public WithEvents TXT As MSForms.TextBox
Private cParent As EventController
Public Sub Initialize(Parent As EventController)
Set Me.Parent = Parent
With Parent.UserForm.Frame7.Controls
Set SP = .Add("Forms.SpinButton.1")
Set TXT = .Add("Forms.TextBox.1")
End With
End Sub
Public Property Set Parent(v As EventController)
Set cParent = v
End Property
Public Property Get Parent() As EventController
Set Parent = cParent
End Property
Public Property Let Left(v As Single)
TXT.Left = v
SP.Left = TXT.Left + TXT.Width
End Property
Public Property Get Left() As Single
Left = TXT.Left
End Property
Public Property Let Top(v As Single)
TXT.Top = v
SP.Top = v
End Property
Public Property Get Top() As Single
Top = TXT.Top
End Property
Public Property Let Height(v As Single)
TXT.Height = v
SP.Height = v
End Property
Public Property Get Height() As Single
Height = TXT.Height
End Property
Public Property Let Width(v As Single)
TXT.Width = v - SP.Width
SP.Left = TXT.Left + TXT.Width
End Property
Public Property Get Width() As Single
Width = TXT.Width + SP.Width
End Property
Public Sub SP_SpinDown()
Parent.SpinDown Me
' SP.Value = SP.Value - 1
' MsgBox "Spin Down to " & SP.Value
End Sub
' The commented out lines below you can either leave in here, or handle in the Userform
Public Sub SP_SpinUp()
Parent.SpinUp Me
' SP.Value = SP.Value + 1
' MsgBox "Spin Up to " & SP.Value
End Sub
Public Sub TXT_Change()
Parent.Change Me
' MsgBox "You changed the value."
End Sub
The issue is stemmed from that when the Userform is loaded the controls aren't loaded and therefore the Userform hasn't registered that they're something that has an Event. By using the intermediary class the Userform recognises that that class has an Event and we load this statically on initialize of the Userform. We can then add in whatever Controls we want to this Class and the Userform will handle them.
Demo:

Set variable with a loop using the variables name as a string

My application requires variables to be set and retrieved multiple times in different forms and subs. Instead of writing the code multiple times i was hoping to use a loop to loop through the variables and set them accordingly. The code below shows my settings menu and how it is built. I'm stuck with setting the variables based on a name that is stored as a string (See last code snippet below).
The section imedialty below are the menu classes. This bit works as expected
Public Class MenuItem
Public Name As String
Public Type As TypeEnum
Enum TypeEnum
CheckBox
ComboBox
TextBox
End Enum
Public Sub New()
End Sub
End Class
Public Class Menu
Public MenuItems() As MenuItem
Public Name As String
Public LinkedVariable as Object
Public Sub New()
End Sub
Public Sub AddMenuItem(ByVal ItemName As String, _
ByVal ItemType As MenuItem.TypeEnum, _
ByVal ItemLinkedVariable as Object)
If MenuItems Is Nothing Then
ReDim MenuItems(0)
Else
ReDim Preserve MenuItems(MenuItems.Length)
End If
MenuItems(MenuItems.Length - 1) = New MenuItem
MenuItems(MenuItems.Length - 1).Name = ItemName
MenuItems(MenuItems.Length - 1).Type = ItemType
MenuItems(MenuItems.Length - 1).LinkedVariable = ItemLinkedVariable
End Sub
End Class
Build the menus in the main form class. This bit works as expected
Public Class Form1
Public Settings As New SettingsForm
Public Sub CreateMenu()
Settings.AddMenu("Menu1")
Settings.Menus(0).AddMenuItem("CheckBoxA", MenuItem.TypeEnum.CheckBox, VariableA)
Settings.Menus(0).AddMenuItem("TextBoxB", MenuItem.TypeEnum.TextBox, VariableB)
Settings.Menus(0).AddMenuItem("TextBoxC", MenuItem.TypeEnum.TextBox, VariableC)
Settings.AddMenu("Menu2")
Settings.Menus(1).AddMenuItem("CheckBoxD", MenuItem.TypeEnum.CheckBox, VariableD)
Settings.Menus(1).AddMenuItem("TextBoxE", MenuItem.TypeEnum.TextBox, VariableE)
'etc......
Settings.Build()
Settings.Show()
End Sub
End Class
Public Class SettingsForm
Public Menus() As Menu
Public VariableA As Boolean
Public VariableB As String
Public VariableC As String
Public VariableD As Boolean
Public VariableE As String
Public Sub New()
InitializeComponent()
End Sub
Public Sub Build()
SettingsTabControl.TabPages.Clear()
If Menus IsNot Nothing Then
For i As Integer = 0 To Menus.Length - 1
SettingsTabControl.TabPages.Add(Menus(i).Name)
SettingsTabControl.TabPages(i).Name = Menus(i).Name & "TabPage"
SettingsTabControl.TabPages(i).Text = Menus(i).Name
AddSettingsItems(Menus(i), i)
Next
End If
End Sub
Public Sub AddSettingsItems(ByVal SelectedMenu As Menu, ByVal TabPageIndex As Integer)
Dim y As Integer = 50
Dim yinc As Integer = 25
If SelectedMenu IsNot Nothing Then
If SelectedMenu.MenuItems IsNot Nothing Then
For i As Integer = 0 To SelectedMenu.MenuItems.Length - 1
Dim formObj As Object
'Specific Settings
Select Case SelectedMenu.MenuItems(i).Type
Case MenuItem.TypeEnum.CheckBox
formObj = New CheckBox
Case MenuItem.TypeEnum.ComboBox
formObj = New ComboBox
Case MenuItem.TypeEnum.TextBox
formObj = New TextBox
formObj.TextAlign = HorizontalAlignment.Right
formObj.BorderStyle = BorderStyle.FixedSingle
End Select
formObj.Name = SelectedMenu.MenuItems(i).Name
formObj.Location = New Point(25, y)
SettingsTabControl.TabPages(TabPageIndex).Controls.Add(formObj)
y = y + yinc
Next
End If
End If
End Sub
End Class
This is the bit i am stuck on i want to be able to set the Variables A,B,C,D,E from the controls that were added to the SettingsTabControl. However i can't work out how to link the Variables to the LinkedVariable objects in each MenuItem. This is what i have but it doesn't work
Private Sub SettingsFromOkButton_Click(sender As Object, e As EventArgs) Handles OkButton.Click
For m As Integer = 0 To Menus.Length - 1
For i As Integer = 0 To Menus(m).MenuItems.Length
Dim currentcontrol As Object = SettingsTabControl.TabPages(m).Controls(Menus(m).MenuItems(i).Name)
Select Case Menus(m).MenuItems(i).Type
Case MenuItem.TypeEnum.CheckBox
If currentcontrol.CheckedState = True Then
Menus(m).MenuItems(i).LinkedVariable = True
Else
Menus(m).MenuItems(i).LinkedVariable = False
End If
Case MenuItem.TypeEnum.ComboBox
Case MenuItem.TypeEnum.TextBox
Menus(m).MenuItems(i).LinkedVariable = currentcontrol.Text
End Select
Next
Next
MsgBox(VariableA & vbCrLf _
VariableB & vbCrLf _
VariableC & vbCrLf _
VariableD & vbCrLf _
VariableE & vbCrLf)
End Sub
I used a reflection
Dim Flags As BindingFlags = BindingFlags.GetField Or BindingFlags.Instance Or BindingFlags.Public
Dim fVar As System.Reflection.FieldInfo = Me.GetType.GetField(ObjectName, Flags)
If TypeOf SettingsTabControl.TabPages(TabPageIndex).Controls(CtrlName) Is TextBox Then
ctrlValue = SettingsTabControl.TabPages(TabPageIndex).Controls(CtrlName).Text
ElseIf TypeOf SettingsTabControl.TabPages(TabPageIndex).Controls(CtrlName) Is CheckBox Then
ctrlValue = CType(SettingsTabControl.TabPages(TabPageIndex).Controls(CtrlName), CheckBox).Checked
ElseIf TypeOf SettingsTabControl.TabPages(TabPageIndex).Controls(CtrlName) Is RadioButton Then
ctrlValue = CType(SettingsTabControl.TabPages(TabPageIndex).Controls(CtrlName), RadioButton).Checked
End If
fVar.SetValue(Me, ctrlValue)

Wait for function to end VB

I'm starting a ne project, in VB. And I have a problem. So maybe I don't understand the logic - can you explain it to me?
In my function Feuil1_BeforeDoubleClick i would like to wait for Button1_Clickto end.
But i don't know how to achieve this.
Here's the relevant code:
My Sheet1 :
Imports System.Threading.Tasks
Imports Microsoft.Office.Interop.Excel
Public Class Feuil1
Friend actionsPane1 As New ActionsPaneControl1
Public list As String
Public Sub Feuil1_BeforeDoubleClick(Target As Range, ByRef Cancel As Boolean) Handles Me.BeforeDoubleClick
If Target.Column <> 1 Then
If Target.Row = 16 Then
Globals.ThisWorkbook.ActionsPane.Controls.Add(actionsPane1)
Globals.ThisWorkbook.Application.DisplayDocumentActionTaskPane = True
'marche pas SendKeys.Send("{ESC}")
'
'wait here for the end of Button1_click
Target.Value = list
list = ""
End If
End If
MsgBox("doubleclick end")
End Sub
End Class
And there is my actionpane1 :
Public Class ActionsPaneControl1
Friend Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim i As Integer
Dim itemChecked As Object
Const barre As String = " / "
For Each itemChecked In CheckedListBox1.CheckedItems
Globals.Feuil1.list = Globals.Feuil1.list + itemChecked.ToString() + barre
Next
' Boucle pour reset la list
For i = 0 To (CheckedListBox1.Items.Count - 1)
CheckedListBox1.SetItemChecked(i, False)
Next
Globals.ThisWorkbook.Application.DisplayDocumentActionTaskPane = False
End Sub
End Class
Example taken from https://www.daniweb.com/programming/software-development/threads/139395/how-to-check-if-a-button-was-clicked . Credit is given.
Basicly declare a variable at form level and then set it to true whenever the button is clicked. Reset it when appropriate
Dim bBtnClicked As Boolean = False
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If bBtnClicked = True Then
MessageBox.Show("This button is clicked already ....")
Else
MessageBox.Show("This button is clicked First time ....")
End If
bBtnClicked = True
End Sub
Alternatively whatever it is that you want to happen after the button is clicked, just put that code in the handler for the button-click event.
So i think about the problem, and it seems I didn't understand my function doubleclick, was not working after the double click but before ! that was my mistake.
So i change my function to detect, the change of selection in my sheet.
Then i call my action pane.
And work with the event of the button of the action pane.
There is the entire code ( maybe because i don't explain me correctly)
my Sheet1.vb :
Imports Microsoft.Office.Interop.Excel
Public Class Feuil1
Friend actionsPane1 As New ActionsPaneControl1
Public list As String
Public cell As Range
Private Sub Worksheet_SelectionChange(ByVal Target As Range) Handles Me.SelectionChange
If Target.Column <> 1 Then
If Target.Row = 16 Then
Globals.ThisWorkbook.ActionsPane.Controls.Add(actionsPane1)
Globals.ThisWorkbook.Application.DisplayDocumentActionTaskPane = True
cell = Target
End If
End If
End Sub
End Class
and my actionpanecontrol1.vb :
Public Class ActionsPaneControl1
Friend Button1Click = False
Friend Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim i As Integer
Dim itemChecked As Object
Const barre As String = " / "
For Each itemChecked In CheckedListBox1.CheckedItems
Globals.Feuil1.list = Globals.Feuil1.list + itemChecked.ToString() + barre
Next
' Boucle pour reset la list
For i = 0 To (CheckedListBox1.Items.Count - 1)
CheckedListBox1.SetItemChecked(i, False)
Next
Globals.ThisWorkbook.Application.DisplayDocumentActionTaskPane = False
Button1Click = True
Globals.Feuil1.cell.Value = Globals.Feuil1.list
Globals.Feuil1.list = ""
End Sub
End Class
Thanks a lot for all your reply

Export only visible columns in datagridview to Excel

I'm currently developing a software as required in my OJT. Im trying to export my datagrid to an excel file. the problem is even if i put checkbox to set the visibility of specific column to false and it hides on my datagrid but when the excel file is generated, the columns are still visible. heres my code, and thank you.
Private Sub Button9_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button9.Click
TabPage1.Enabled = False
TabPage2.Enabled = False
'Form3.Show()'
DATAGRIDVIEW_TO_EXCEL((DataGridView1))
End Sub
'-------------------------------------------------Excel------------------------------------------------'
Private Sub DATAGRIDVIEW_TO_EXCEL(ByVal DGV As DataGridView)
Try
Dim DTB = New DataTable, RWS As Integer, CLS As Integer
For CLS = 0 To DGV.ColumnCount - 1
DTB.Columns.Add(DGV.Columns(CLS).Name.ToString)
Next
Dim DRW As DataRow
For RWS = 0 To DGV.Rows.Count - 1
DRW = DTB.NewRow
For CLS = 0 To DGV.ColumnCount - 1
Try
DRW(DTB.Columns(CLS).ColumnName.ToString) = DGV.Rows(RWS).Cells(CLS).Value.ToString
Catch ex As Exception
End Try
Next
DTB.Rows.Add(DRW)
Next
DTB.AcceptChanges()
Dim DST As New DataSet
DST.Tables.Add(DTB)
Dim FLE As String = "E:\Export\Export.xml"
DTB.WriteXml(FLE)
Dim EXL As String = "C:\Program Files\Microsoft Office\Office15\EXCEL.exe"
Shell(Chr(34) & EXL & Chr(34) & " " & Chr(34) & FLE & Chr(34), vbNormalFocus)
Catch ex As Exception
MsgBox(ex.ToString)
End Try
'------------------------------------------------------Excel--------------------------------------------------------'
End Sub
Here is how i hide my columns
Private Sub CheckBox1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged
If CheckBox1.Checked = True Then
Me.GSIS.Visible = False
Else
Me.GSIS.Visible = True
End If
End Sub
Private Sub CheckBox2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox2.CheckedChanged
If CheckBox2.Checked = True Then
Me.PAGIBIG.Visible = False
Else
Me.PAGIBIG.Visible = True
End If
End Sub
Private Sub CheckBox3_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox3.CheckedChanged
If CheckBox3.Checked = True Then
Me.PHILHEALTH.Visible = False
Else
Me.PHILHEALTH.Visible = True
End If
End Sub
Private Sub CheckBox4_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox4.CheckedChanged
If CheckBox4.Checked = True Then
Me.SSS.Visible = False
Else
Me.SSS.Visible = True
End If
End Sub
Private Sub CheckBox5_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox5.CheckedChanged
If CheckBox5.Checked = True Then
Me.TIN.Visible = False
Else
Me.TIN.Visible = True
End If
End Sub
Private Sub CheckBox6_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBox5.CheckedChanged
If CheckBox6.Checked = True Then
Me.AgencyEmployeeNo.Visible = False
Else
Me.AgencyEmployeeNo.Visible = True
End If
End Sub
I would change this:
For CLS = 0 To DGV.ColumnCount - 1
DTB.Columns.Add(DGV.Columns(CLS).Name.ToString)
Next
To something like this:
'For Every Column in the DataGridView
For Each Col as DataGridViewColumn in DGV.Columns
If Checkbox1.checked = True AND Col.Name = GSIS.Name Then
DTB.Columns.Add(Col.Name.ToString)
End If
'If checkbox2 etc etc
Next
The Ideal so you wouldn't have to copy paste so much would be to create a class where you would associate a visibility property for each col and would just check that property in a loop.
/!\ Be Careful /!\
I added Col.Nale = GSIS.Name assuming GSIS was a Column but in your code it may not be the case. So try to understand the code instead of copy pasting.

Resources