VB.NET : How to resize DatagridView column width, when application is running? - vb.net

In VB I am working with Windows forms DatagridView.
So here I am trying to get the feature where after running the application, user should be able to resize the column width(On the Fly).
I have gone through lot of stuff but they only provide static solutions. But what I want to achieve is after the application has started running, then if user wants to customise the column width, what is the option for that?

I'm not sure about being able to do this with the standard .NET DataGridViews, but if you download and use the infragistic controls they allow you to change column widths on the fly as standard.

Unless you set the AllowUserToResizeColumns propery to false, the user should be able to modify them however they want with their mouse, just like a "standard" grid like in Excel.
However, I suspect you're asking how to you preserve that setting, so that next time they run it, the column(s) are set back to the user's preference?
One way to do that is to handle the ColumnWidthChanged event on the event and store the value in the registry:
Private Sub DataGridView1_ColumnWidthChanged(sender As Object, e As System.Windows.Forms.DataGridViewColumnEventArgs) Handles data1.ColumnWidthChanged
Dim dt As DataGridView
dt = DirectCast(sender, DataGridView)
With My.Computer.Registry
.CurrentUser.CreateSubKey(csRegKey & "\Columns\" & dt.Name)
.SetValue("HKEY_CURRENT_USER\" & csRegKey & "\Columns\" & dt.Name, e.Column.Name, e.Column.Width, Microsoft.Win32.RegistryValueKind.DWord)
End With
End Sub
Where csRegKey is a constant string value of your choice defining where in the HKCU hive to store the value, eg "Software\MyAppName".
Then, when your app starts up, read the registry for those values and apply them accordingly to the column widths:
Dim key As Microsoft.Win32.RegistryKey
key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(csRegKey & "\Columns\YourDataName")
If key IsNot Nothing Then
For Each colAny As DataGridViewColumn In Me.data1.Columns
If key.GetValue(colAny.Name) <> 0 Then
colAny.Width = key.GetValue(colAny.Name)
End If
Next
key.Close()
End If

Related

Update NumericUpDown.Maximum from corresponding txt.text control using for each loop

As newbie in VBA.net i want to solve following.
I have a form with 38 text controls in 4 groupboxes. These get filled by clicking a row in a datagridview. I have 38 corresponding NUD's where i want the maximum to be equal to its corresponding text.
A 'pair' is always in one of the 4 groupboxes. Besides that there are also textboxes on the form itself to control the DGV.
I have a naming convention that makes it possible to match them easily . NUDGeel corresponds with txtGeel , NUDRood with TxtRood, NUDGroen with txtGroen etc et
Now that update is easily done if you do them one by one
NUDGeel.maximum = txtGeel.text
NUDRood.maximum = txtRood.text
etc
What i want to achieve is that this gets done in a for each loop. (Order to prevent me typing this 38 times (and also just to 'understand' it)
I can figure out how to start the loop
Dim c As Control
For Each c In Me.Controls
If TypeName(c) = "NumericUpDown" Then
'do some magic
End If
Next
I have tried to search for the magic code, and i guess from research it is pretty simple, i just donot get it .
Anyone with an idea how to fix ?
For Each tb In Controls.OfType(Of TextBox)
Dim nud = DirectCast(Controls(tb.Name.Replace("txt", "NUD")), NumericUpDown)
If nud IsNot Nothing Then
nud.Maximum = CDec(tb.Text)
End If
Next
You don't need the If statement if there are no other TextBoxes on the form besides those with corresponding NumericUpDowns.
Private Sub SetMaximum()
Dim controlNames() As String = {
"Geel", "Rood", "Name1", "Name2", ' list all the names of your controls here excluding NUD/txt
}
For Each controlName As String In controlNames
CType(Me.Controls("NUD" & controlName),NumericUpDown).Maximum = CType(Me.Controls("txt" & controlName),TextBox).Text
Next
End Sub
This assumes that all the controls are not inside any containers. If they are, you must use the container (panel, groupbox, etc) instead of Me.

VB.NET Check for keydown on dragdrop

I've tried searching quite a bit for this answer but haven't been able to find a good solution.
I have a datagridview on my form where users can drag and drop files onto the grid and certain columns are filled in. This works fine.
I want to be able to check if a user has a certain key pressed at the time the file is dropped. If so, I want to use that to add specific data to one of the columns in the datagrid.
Is this possible?
EDIT:
I have used keydown outside of dragdrop before but it seems that I'm missing something. The code I have is below. No matter what I do, I never get "T is pressed" but I always get "T is not pressed".
Private Sub frmReader_DragDrop(sender As Object, e As DragEventArgs) Handles Me.DragDrop
Dim files As String() = CType(e.Data.GetData(DataFormats.FileDrop), String())
If Keyboard.IsKeyDown(Keys.T) Then
MsgBox("T is pressed.")
' Put certain info into the datagridview
Else
MsgBox("T is not pressed.")
' Put other data into the datagridview
End If
End Sub
God, embarassing... I changed "Keys.T" to "Key.T" and it's working fine. Sorry for the bother.

Access button to open multiple reports depending on user input

I am new to access so this might be an easy task or I am just trying to tackle it wrongly. I have a report that has various columns, sample id, sample time, sample type, dry matter, moisture. I am trying to create a button that has an input box for the user to chose what column to sort the report by. So far I thought of creating various reports that have been sorted by each column, named the reports by the column that sorts them then I am trying to have the open report action have a parameter that opens the report linked to the column entered at the input box. Is this even possible or is there a workaround for this.
PS. I am avoiding creating various buttons since it will fill up the screen.
Okay, this is pretty generic and will require some tweaking but it shows the core of how to do this.
To start with you need a module (so not form/report code). This is where the globals will be assigned values:
Option Compare Database
Option Explicit
Global rptname As String
Global fldname As String
Sub setRptName(name As String)
rptname = "Report Sorted by: " & name
fldname = name
End Sub
You will call that code inside the Click() event of your command button on your form and then open the report after that. This will take a combo box value and pass that value to the module code, creating the two global variables.:
Private Sub cmd_report_Click()
mdl_Globals.setRptName Me.cmb_fields.Value
DoCmd.OpenReport "Report1", acViewPreview
End Sub
I'm unsure if this will work with non-preview views, but you probably want preview anyway.
Lastly in the report code behind, you need the Load() and open() events, you may be able to get it to work with both inside one or other but I know this one works.
So to set the caption:
Private Sub Report_Load()
Me.lbl_header.Caption = rptname
End Sub
And then to sort:
Private Sub report_open(Cancel As Integer)
Me.Report.OrderBy = "[" & fldname & "]"
Me.Report.OrderByOn = True
End Sub
If your entry box on the form does not have entries that exactly match the name(s) of the fields in the table you will get a parameter popup.

Changing Textbox.DefaultValue in Access

I would like to be able to change the Textbox.DefaultValue during the 'On Load' event of a form such that each time the form is loaded the user is prompted with an InputBox to change a specific TextBox.Default value which in my case the TextBox control on the table is called Stream. I have tried the following code but each time it gives me a
'RunTime Error 3422 Cannot modify table structure. Another user has
the table open'.
Private Sub Form_Load()
CurrentDb.TableDefs("Class 1 Students (C1)").Fields("Stream").DefaultValue = InputBox("Enter Stream Letter:")
End Sub
I am using Microsoft Access
As Doug Glancy said in a comment, don't change the field's default value in table design. Instead change the text box's default value.
This is a critical point in a multi-user database application --- you wouldn't want one user stomping on another's default value choice. But, even if this will always be a single-user application, changing the table design means you can't have the table open in the record source of your form.
Changing the text box default value is easy. I added an unbound text box, txtDefaultStream, to my form's header. And, in its after update event, I change Me.txtStream.DefaultValue. The code is below.
Here is a screenshot of that form in action. I had A as the default when entering the first 2 rows. Then entered B in the default stream text box. Notice the new record has B in its Stream text box.
Private Sub txtDefaultStream_AfterUpdate()
Dim strDefault As String
If Len(Trim(Me.txtDefaultStream & vbNullString)) > 0 Then
strDefault = """" & Me.txtDefaultStream.value & """"
Me.txtStream.DefaultValue = strDefault
Else
Me.txtStream.DefaultValue = vbNullString
End If
End Sub
As Doug Glancy said, use the textbox, so you should try
Private Sub Form_Load()
Me.AText.DefaultValue = "='S'"
End Sub

Is there any other way to validate textbox values in VB.net

I am trying to validate textbox values during runtime in vb.net I have following code which is validating txtno from database table tblmachines. But i have problem with chartype and stringtype. Is there any other solution to fix that problem?
Private Sub txtno_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtno.KeyPress
If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Return) Then
e.Handled = True
If (Me.txtno.Text = "") Then
Interaction.MsgBox("!!!!!!!!Machine number can not be empty. Please Correct.!!!!!!!!", &H40, "Check Machine Number")
Me.txtno.Focus()
ElseIf (Me.txtno.Text = "0") Then
Me.txtturnover.Focus()
Else
Dim table As DataTable = Me.DataSet1.Tables.Item("tblmachines")
Dim defaultView As DataView = table.DefaultView
defaultView.RowFilter = ("local_no='" & Me.txtno.Text & "'")
If ((Char.IsLetter(CharType.FromString(Me.txtno.Text)) Or (defaultView.Count = 0)) Or (StringType.StrCmp(Me.txtno.Text, "", False) = 0)) Then
Interaction.MsgBox("This machine is not on database. Please correct machine number.", &H40, "Check Machine Number")
Me.txtno.Focus()
Else
Me.txtturnover.Focus()
End If
End If
End If
I think you'd be better off using validation from the Winforms library than in the KeyPress event. KeyPress is going to cause a lot of validation scripts to be run and will bog down your app.
I think you should do the validation in the following steps
Check to ensure that there is data in the texbox
Validate that the data entered in the textbox is in the proper format. You can use regular code, or possibly a RegEx for that.
Validate that the number entered is a part of the database. I made it a habit reset the filters to a blank string before applying any new filters to the table.
The good part about using inbuilt validation is that you do not have to worry about moving focus around.
The control has a property called CausesValidation - if you set it to true (which it already is) then this control will run the validation code. If you do not want the control to run validation code, you can turn the property to False.
The validation happens as Focus shifts - so when you focus off a control, it's validation events are fired.
The events Validating and Validated are commonly used for this purpose. You can put your code validation in there instead of putting it on the KeyPress.
This is not the proper way to let the user input this specific data. You've got a list of valid entries available from your database. Put them in a ComboBox so the user doesn't have to guess and can't get it wrong.