visible combobox after update other combobox access - vba

i have 3 combobox
cmbMaterial_Type data = SELECT [tblMaterialType].[Material_Type_ID], [tblMaterialType].[Material_Type] FROM tblMaterialType
cmbMaterial_Thick data = SELECT [tblMaterialThick].[Material_Thick_ID], [tblMaterialThick].[Material_Thick] FROM tblMaterialThick WHERE ((([tblMaterialThick].[Material_Type_ID])=Forms!frmMaterial!cmbMaterial_Type));
cmbMaterial_DegreeIsolation data = SELECT [tblMaterialDegreeIsolation]. [Degree_Isolation_ID], [tblMaterialDegreeIsolation].[Degree_Isolation] FROM tblMaterialDegreeIsolation WHERE ((([tblMaterialDegreeIsolation].[Material_Type_ID])=Forms!frmMaterial!cmbMaterial_Type));
MaterialType is parent and have 2 child 1-MaterialThick 2-DegreeIsolation
my table column and relation
i added code on change for load combobox cmbMaterial_Thick or cmbDegreeIsolation
Private Sub cmbMaterial_Type_Change()
Me.cmbMaterial_Thick.Value = ""
Me.cmbMaterial_DegreeIsolation.Value = ""
End Sub
i want after update my cmbMaterial_Type
if cmbMaterial_Type have some data in combobox 1 in picture then visible it and hide 2
else
visible 2 and hide 1
i use this code but not work
Private Sub cmbMaterial_Type_AfterUpdate()
If MaterialType = cmbMaterial_Thick.Value Then
cmbMaterial_Thick.Visible = True
cmbMaterial_DegreeIsolation.Visible = False
Else
cmbMaterial_Thick.Visible = False
cmbMaterial_DegreeIsolation.Visible = True
End If
End Sub

Related

DataGridView live search data

I am trying to add a search function to a DataGridView in vb.net using this code
For i As Integer = 0 To ContactsList.RowCount - 1
For j As Integer = 0 To ContactsList.ColumnCount - 1
If ContactsList.Rows(i).Cells(j).Value.ToString.ToLower.Trim = ContactsListSearch.Text.ToLower.Trim Then
MsgBox("Item found " + i.ToString)
ContactsList.Rows(i).Visible = True
Else
ContactsList.Rows(i).Visible = False
End If
Next
Next
I'm seeing the MsgBox show when the value matches, but the rows are not showing, it just hides all rows
Another possible option is to load data into a DataTable, create a BindingSource, set the BindingSource DataSource property to the DataTable. Set the DataGridView DataSource property to the BindingSource.
The following example works against a column in the DataTable. If the user clears the TextBox the filter is removed while if there is text filter with trim.
Private Sub SearchButton_Click(sender As Object, e As EventArgs) _
Handles SearchButton.Click
If String.IsNullOrWhiteSpace(SearchTextBox.Text) Then
bindingSource.Filter = ""
Else
Dim currentRowCount = bindingSource.Count
bindingSource.Filter = $"TRIM(LastName) = '{SearchTextBox.Text}'"
MessageBox.Show($"Before: {currentRowCount} Now: {bindingSource.Count}")
End If
End Sub
Edit If the column name might be variable consider loading a ComboBox with column names then adjust code as follows.
bindingSource.Filter = $"TRIM({FilterComboBox.Text}) = '{SearchTextBox.Text}'"
In most cases working against a data source is better than working against cells values as per the above recommendation.
I added 2 Exits in the IF statement when the value matches as it's searching each column as well, so it was causing them to be hidden as it loops columns too
For i As Integer = 0 To ContactsList.RowCount - 1
For j As Integer = 0 To ContactsList.ColumnCount - 1
If ContactsList.Rows(i).Cells(j).Value.ToString.ToLower.Trim = ContactsListSearch.Text.ToLower.Trim Then
MsgBox("Item found " + i.ToString)
ContactsList.Rows(i).Visible = True
Else
ContactsList.Rows(i).Visible = False
End If
Next
Next

How to freeze merged columns in data grid view when scrolling vertically?

I have a data grid view where I need the columns to be frozen or fixed when scrolling vertically.
I have a data grid view control in vb.net windows application which displays the data in a parent-child hierarchy(as shown below). The first column displays the parent data and the second column displays all its child data. The child data in the second column can be as much as 100 rows or even more. So when scrolling down through the grid, the value in the first column does not remain there as it is while the values in the second column(i.e. the child data) scrolls down. So if the user wants to check to which parent, the current child info belongs to, then again he will have to scroll up to the starting of the column to find the name of the parent. I want the values in the first column to be displayed or frozen till it reaches the end of the list of its child values in the grid or at least till the next row where the next parent data starts. I have suggested the client to go with a tree view but they are not agreeing and need it in a data grid view itself. Is there anyway to achieve this in a data grid view?
Thanks in advance.
You can't freeze a row (in runtime, on dgv scrolling) with index greater than zero because all those before are frozen and at that point you can't scroll your datagridview.
If I understood correctly what you want I wrote this class quickly (probably should be optimized). Usage is simple.
1 - First create your own datagridview.
2 - then add your columns and rows (IMPORTANT: Put a “X” in the Tag in each row is a Parent or is considered as title for other rows as you seen in TestPopulate method) .
3 - Call the class I made by passing the datagridview (you created first) as a parameter. At this point this control takes its size, placement and REPLACE YOUR DATAGRIDVIEW .
Private Class CustomDgv
Inherits Panel
Dim WithEvents TopDgv As DataGridView = New DataGridView
Dim WithEvents DownDgv As DataGridView = New DataGridView
Dim Cols As Integer
' This variable is in case you have more rows as "headrow"
' In TestPopulate you can see how to get those
Dim listOfOwnerRows As List(Of Integer) = New List(Of Integer)
Dim currentTopRow As Integer = -1
Protected Overloads Property Height As Integer
Get
Return MyBase.Height
End Get
Set(value As Integer)
MyBase.Height = value
TopDgv.Height = TopDgv.RowTemplate.Height - 1
DownDgv.Height = value - TopDgv.Height - 1
End Set
End Property
Protected Overloads Property Width As Integer
Get
Return MyBase.Width
End Get
Set(value As Integer)
MyBase.Width = value
TopDgv.Width = value - 1
DownDgv.Width = value - 1
End Set
End Property
Sub New(dgvOriginal As DataGridView)
DownDgv = dgvOriginal
Dim parentCtrl As Control = dgvOriginal.Parent
parentCtrl.Controls.Remove(dgvOriginal)
parentCtrl.Controls.Add(Me)
Me.Location = DownDgv.Location
Me.Size = DownDgv.Size
Me.BorderStyle = DownDgv.BorderStyle
TopDgv.Width = Width - 2 - SystemInformation.VerticalScrollBarWidth
TopDgv.Height = TopDgv.RowTemplate.Height
TopDgv.ScrollBars = ScrollBars.None
TopDgv.ColumnHeadersVisible = False
TopDgv.BorderStyle = BorderStyle.None
DownDgv.ColumnHeadersVisible = False
DownDgv.BorderStyle = BorderStyle.None
TopDgv.Left = 0
DownDgv.Left = 0
DownDgv.Width = Width - 2
DownDgv.Height = Height - 2
For Each Col As DataGridViewColumn In DownDgv.Columns
Dim cIndex As Integer = TopDgv.Columns.Add(Col.Clone)
If Col.Frozen Then
TopDgv.Columns(cIndex).Frozen = True
End If
Cols += 1
Next
DownDgv.Top = 0
Me.Controls.Add(TopDgv)
Me.Controls.Add(DownDgv)
If DownDgv.Rows.Count > 0 Then
listOfOwnerRows = (From R As DataGridViewRow In DownDgv.Rows
Where R.Tag = "X"
Select R.Index).ToList
If listOfOwnerRows.Count > 0 Then
SetFrosenRow(listOfOwnerRows(0))
End If
End If
End Sub
Protected Sub SetFrosenRow(index As Integer)
If DownDgv.Rows.Count > index Then
TopDgv.Rows.Clear()
TopDgv.Rows.Add()
Dim currentRIndex As Integer = DownDgv.FirstDisplayedScrollingRowIndex
'If you want onlly the base row
For i As Integer = 0 To Cols - 1
TopDgv.Rows(0).Cells(i).Value = DownDgv.Rows(index).Cells(i).Value
Next
'Or else get the diplayed on top row
TopDgv.Rows(0).DefaultCellStyle = New DataGridViewCellStyle With {
.BackColor = Color.Bisque
}
currentTopRow = index
End If
End Sub
Protected Sub SetChildValuesInTopRow(index As Integer)
For i As Integer = 1 To Cols - 1
TopDgv.Rows(0).Cells(i).Value = DownDgv.Rows(index).Cells(i).Value
Next
End Sub
Private Sub DownDgv_Scroll(sender As Object, e As ScrollEventArgs) Handles DownDgv.Scroll
Try
If e.ScrollOrientation = ScrollOrientation.VerticalScroll Then
Dim topR As Integer = DownDgv.FirstDisplayedScrollingRowIndex
'If you want in top row the current value that is in the top uncomment this
SetChildValuesInTopRow(topR)
If listOfOwnerRows.Count > 0 Then
Dim rToSetAsOwner As Integer = listOfOwnerRows(listOfOwnerRows.Count - 1)
For i As Integer = listOfOwnerRows.Count - 1 To 0 Step -1
If listOfOwnerRows(i) <= topR Then
rToSetAsOwner = listOfOwnerRows(i)
Exit For
End If
Next
If rToSetAsOwner <> currentTopRow Then
SetFrosenRow(rToSetAsOwner)
End If
Console.WriteLine("rToSetAsOwner: " & rToSetAsOwner)
End If
Else
TopDgv.HorizontalScrollingOffset = DownDgv.HorizontalScrollingOffset
End If
Catch ex As Exception
Console.WriteLine(ex.ToString)
End Try
End Sub
End Class
Usage:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
Try
' first populate you grid putting a tag in each row which is a header/parent/title for other rows
TestPopulate()
Dim customControl As Control = New CustomDgv(DataGridView1)
Catch ex As Exception
Console.WriteLine(ex.ToString)
End Try
End Sub
Sub TestPopulate()
For i As Integer = 0 To 100
DataGridView1.Rows.Add()
If i = 0 Then
DataGridView1.Rows.Item(0).Cells(0).Value = "Owner 0"
DataGridView1.Rows(0).Tag = "X"
End If
If i = 50 Then
DataGridView1.Rows.Item(50).Cells(0).Value = "Owner 50"
DataGridView1.Rows(50).Tag = "X"
End If
If i = 70 Then
DataGridView1.Rows.Item(70).Cells(0).Value = "Owner 70"
DataGridView1.Rows(70).Tag = "X"
End If
DataGridView1.Rows.Item(i).Cells(1).Value = "child_" & i.ToString & "_1"
DataGridView1.Rows.Item(i).Cells(2).Value = "child_" & i.ToString & "_2"
Next
End Sub
I hope I have been helpful

How To Update A Janus GridEx Checkbox At Runtime

I have a Janus GridEx control named grdLOB that can have multiple rows. Each row has a checkbox and 3 additional columns. If a checkbox is unchecked on a certain row (GL) I need to loop thru the grid and uncheck the checkboxes in the other rows.
Here is the code I have, but obviously it's not working...
Private Sub grdLOB_CellValueChanged(ByVal sender As Object, ByVal e as Janus.Windows.GridEX.ColumnActionEventArgs) Handles grdLOB.CellValueChanged
If e.Column.Key = cSelector Then
Dim grd As Janus.Windows.GridEX.GridEX = CType(sender, GridEX)
Dim row As GridEXRow = grd.GetRow(grd.Row)
Select Case row.Cells(1).Value.ToString().ToUpper()
Case "GL"
'If GL is checked, do nothing to the other rows.
'If GL is unchecked, uncheck all the other rows.
If CBool(row.Cells(0).Value) = False Then
For Each gr As GridEXRow In grdLOB.GetRows()
gr.BeginEdit()
gr.Cells(0).Value = False
gr.EndEdit()
Next
End If
Case Else
'If a row other than GL is unchecked, do nothing to the other rows.
'If a row other than GL is checked, then check the GL row.
If CBool(row.Cells(0).Value) = True Then
For Each gr As GridEXRow In grdLOB.GetRows()
If gr.Cells(1).Value = "GL" Then
gr.BeginEdit()
gr.Cells(0).Value = True
gr.EndEdit()
End If
Next
End If
End Select
End If
End Sub
How can I dynamically check\uncheck checkboxes in the GridEx?
Figured it out. Here's the changed Select Case code that works:
Select Case row.Cells(1).Value.ToString().ToUpper()
Case "GL"
'If GL is checked, do nothing to the other rows.
'If GL is unchecked, uncheck all the other rows.
If CBool(row.Cells(0).Value) = False Then
For i As Integer = 0 To grdLOB.RowCount - 1
Dim gr As GridEXRow = grdLOB.GetRow(i)
gr.IsChecked = False
Next
End If
Case Else
'If a row other than GL is unchecked, do nothing to the other rows.
'If a row other than GL is checked, then check the GL row.
If CBool(row.Cells(0).Value) = True Then
For i As Integer = 0 To grdLOB.RowCount - 1
Dim gr As GridEXRow = grdLOB.GetRow(i)
If gr.Cells(1).Value = "GL" Then
gr.IsChecked = True
End If
Next
End If
End Select

Change value of row to image based on cell value

Hi everyone i am doing a windows form which is created in visual studio 2005, wherein it displays data in datagridview. I have a column "colImg" that will display 1 and 0. But i need to display a red image when the value of cell of colImg is 0 and green image when the value is 1. I have a code but the problem is it only displays image which is green but i have a values which is 0. Is there any problem on my code?
Private Sub grdView_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles grdView.CellFormatting
If grdView.Columns(e.ColumnIndex).Name.Equals("colImg") Then
Dim value As Integer
If TypeOf e.Value Is Integer Then
value = DirectCast(e.Value, Integer)
e.Value = My.Resources.Resources.NotYet
Else
For i As Integer = 0 To grdView.RowCount
If value = 0 Then
e.Value = My.Resources.Resources.Red
Else
e.Value = My.Resources.Resources.Green
End If
Next
End If
End If
There are several solutions for your question, I will provide one of them.
You need two columns in your DataGrid.
One is to hold the raw data (0 or 1); in my example I called it colValue.
The other is to hold only the image (red or green); named colImg.
colValue is not shown in the grid :
'Set colValue invisible which is first column in my example
DataGridView1.Columns(0).Visible = False
Use the CellValueChanged event to set the image of the colImg cell:
If e.ColumnIndex = 0 AndAlso Not isInit Then 'Value column has changed and we are not in Form Initializing
Dim valueCell = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex)
Dim imgCell = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex + 1) 'Whatever index your colImg is
If Integer.Parse(valueCell.Value.ToString()) = 1 Then
imgCell.Value = My.Resources.Green
Else
imgCell.Value = My.Resources.Red
End If
End If
To avoid that the event code breaks when the Form and thus the DataGridView is being initilized I created a local variable isInit and set it before and after the initialization:
Public Class Form1
Private isInit As Boolean
Public Sub New()
isInit = True
InitializeComponent()
isInit = False
...
End Sub
...
End Class
Sample Data:
DataGridView1.Rows(0).Cells(0).Value = 1
DataGridView1.Rows(1).Cells(0).Value = 0
DataGridView1.Rows(2).Cells(0).Value = 0
DataGridView1.Rows(3).Cells(0).Value = 1
Outcome:

Setting ReadOnly attribute to all Textboxes in Array of Controls

I have the following code looping through a variety of arrayed controls in a form:
For r As Long = LBound(ctrlArray) To UBound(ctrlArray)
If TypeOf ctrlArray(r) Is TextBox Then
ctrlArray(r).Text = ""
If ctrlArray(r).ReadOnly = False Then
ctrlArray(r).ReadOnly = True
End If
Else
If ctrlArray(r).Enabled = True Then
ctrlArray(r).Enabled = False
End If
End If
Next
I receive the error "'ReadOnly' is not a member of System.Windows.Forms.Control" when trying to set textboxes as read only.
Solved this right before I hit the submit button. Thought I would share anyway:
Dim tbx As TextBox
For r As Long = LBound(ctrlArray) To UBound(ctrlArray)
If TypeOf ctrlArray(r) Is TextBox Then
ctrlArray(r).Text = ""
tbx = ctrlArray(r)
If tbx.ReadOnly = False Then
tbx.ReadOnly = True
End If
Else
If ctrlArray(r).Enabled = True Then
ctrlArray(r).Enabled = False
End If
End If
Next