Or function only looks at first value - vb.net

Private Sub btnSubmit_Click(sender As Object, e As EventArgs) Handles btnSubmit.Click
Dim difficulty As Integer 'Sets difficulty as integer
If txtBack.Visible = True Or btnDisplay.Enabled = False Then 'if back of the flashcard is visible and if the start button has been clicked
If Integer.TryParse(TxtDifficulty.Text, difficulty) AndAlso difficulty >= 1 AndAlso difficulty <= 3 Then 'If diffiuclty is between 1 and 3
Dim front = txtFront.Text 'Defines front as variable which is equal to txtfront.text
UpdateDifficultyLevel(front, difficulty) 'Calls subroutine
MsgBox("Difficulty updated succesfully") 'outputs messagebox saying difficulty has been updated succesfully
Else 'If user input is not an integer
MsgBox("Please enter a number between 1 and 3") ' tells user that the difficulty must be a number
End If
Else 'If back of the flashcard is not visible and is start button has not been clicked
MsgBox("Please display the flashcard") 'Tells user to display flashcard.
End If
End Sub
This code is supposed to check if txtback.visible = true or btndisplay.enabled = false then runs the appropriate code. However only the txtback.visible works. How would I get the code to also check if btndisplay.enabled = false?

Are you sure you want to use Or? The comment on that if statement says:
"if condition1 AND condition2 are true, then...". In that case, if you want both to be checked and evaluated as true just do
If txtBack.Visible = True And btnDisplay.Enabled = False Then

Related

how to make flashcards that the user gets wrong appear more often - visual basic

I am creating a flashcard application which displays flashcards that the user has created
Private Sub btnDisplay_Click(sender As Object, e As EventArgs) Handles btnDisplay.Click
btnDisplay.Enabled = False
Dim index = rand.Next(dt.Rows.Count) ' generates index in the range 0 .. Count - 1
txtFront.Text = dt.Rows(index)(2).ToString()
txtBack.Visible = False
txtBack.Text = dt.Rows(index)(3).ToString()
End Sub
Private Sub btnEasy_Click(sender As Object, e As EventArgs) Handles btnEasy.Click
Dim index = rand.Next(dt.Rows.Count) ' generates index in the range 0 .. Count - 1
If txtBack.Visible = True Then
txtFront.Text = dt.Rows(index)(2).ToString()
txtBack.Visible = False
txtBack.Text = dt.Rows(index)(3).ToString()
Else
MsgBox("Please first reveal the back of the flashcard")
End If
End Sub
Private Sub btnGood_Click(sender As Object, e As EventArgs) Handles btnGood.Click
Dim index = rand.Next(dt.Rows.Count) ' generates index in the range 0 .. Count - 1
If txtBack.Visible = True Then
txtFront.Text = dt.Rows(index)(2).ToString()
txtBack.Visible = False
txtBack.Text = dt.Rows(index)(3).ToString()
Else
MsgBox("Please first reveal the back of the flashcard")
End If
End Sub
Private Sub btnHard_Click(sender As Object, e As EventArgs) Handles btnHard.Click
Dim index = rand.Next(dt.Rows.Count) ' generates index in the range 0 .. Count - 1
If txtBack.Visible = True Then
txtFront.Text = dt.Rows(index)(2).ToString()
txtBack.Visible = False
txtBack.Text = dt.Rows(index)(3).ToString()
Else
MsgBox("Please first reveal the back of the flashcard")
End If
End Sub
Private Sub btnReveal_Click(sender As Object, e As EventArgs) Handles btnReveal.Click
txtBack.Visible = True
End Sub
The current code displays a random flashcard that is stored in an access database. I was wondering if there is a way where flashcards that the user gets wrong appear more often(kind of like anki).
So, if the user clicks the btnEasy button, the flashcard is less likely to come up again and if the user presses the btnHard button, the flashcard is more likely to come up.
For each card, you can track some GoodUntil DateTime variable which represents the time at which it should be shown again, like Anki does. When cards are first created, you set that value to Now so the card can be immediately shown to the student. Then, every time the student sees the card, you update GoodUntil to a new date based on what the student clicks (Easy, Good, Difficult, etc). For example, if the user clicks:
Easy: set GoodUntil to 10 days from now
Good: set GoodUntil to 2 days from now
Difficult: set GoodUntil to 5 minutes from now.
When looking for the next card to show, look at each card's GoodUntil value and compare it with Now. If it's less than 0, it's ready to be shown again.
This is a basic way to do this but should work well. You should also track a score for each card which will track how well a student is doing with the card. If the student clicks Easy on a card, you want to keep track of that and next time, if he clicks Easy again, you can set the GoodUntil date to 30 days, then 60 days if he clicks Easy again, etc.
When no more cards can be found, you can display some message to the student telling them they are done studying.

VB.net Navigating Text Adventure Game

I am working on a text adventure game. The goal of this program is to display three options and a textbox. The user can select one of the options by entering the corresponding number into a text box, which then is supposed to navigate the user into the next area, where the user is presented with another 3 options.
The issue I am currently having is navigating through the area game areas.
Sub gameOver(ByVal DeathMessage)
lblTitle.Text = "Game Over!"
lblMain.Text = DeathMessage
End Sub
Sub pgMain()
lblMain.Text = $"Enter 1 to start the game{vbCrLf}Enter 2 to quit the game"
If aryInput(0) = "1" Then
pg1()
ElseIf aryInput(0) = "2" Then
Me.Close()
End If
End Sub
Private Sub btnSubmit_Click(sender As Object, e As EventArgs) Handles btnSubmit.Click
aryInput(0) = tbxInput.Text
End Sub
Sub pg1() ' User picks a starting option
lblTitle.Text = "You spot a secret magical lair do you"
lblMain.Text = $"1. Enter the lair through the front door{vbCrLf}2. Enter the lair through the back door{vbCrLf}3. Wait untill midnight to enter the lair."
If aryInput(0) = "1" Then
MsgBox("Front door") 'pg2()
ElseIf aryInput(0) = "2" Then
MsgBox("backdoor")
pg3()
ElseIf aryInput(0) = "3" Then
gameOver("You were mauled by wolves")
End If
End Sub
'Sub pg2() ' User entered through the front door.
' lblMain.Text = $"1. Go to the chest{vbCrLf}2. Go to the bookshelf{vbCr}3. Go to the cauldron"
' If tbxInput.Text = "1" Then
' pg5() ' They went to the chest
' ElseIf tbxInput.Text = "2" Then
' pg6() ' User went to the bookshelf
' ElseIf tbxInput.Text = "3" Then
' pg7() ' User went to the cauldron
' End If
'End Sub
Sub pg3()
tbxInput.Text = Nothing
lblTitle.Text = "You were splashed with a poison spell do you"
lblMain.Text = $"1. Cut off the infected part{vbCrLf}2. Drink a bucket of milk{vbCrLf}3. Inject yourself with some sort of medical syringe"
If tbxInput.Text = "1" Then
MsgBox("Infected Part") 'pg8()
ElseIf tbxInput.Text = "2" Then
MsgBox("Milk") 'pg9()
ElseIf tbxInput.Text = "3" Then
gameOver("You injected yourself with viper venom.")
End If
End Sub
As you can probably tell I am having issues with getting the content of the textbox to decide where the user will go next. I have tried using Input Boxes, and yes it works but they have a character limit and I would prefer figuring out a way to do this with a text box. I was also considering a way using key presses instead of a button click. Sorry for the beginner question, I am still learning my way around Visual Basic. Thank you in advance!
I like radio buttons better because it is easier to control user input. A user can put anything in a text box and you need to handle the possibility that it is not 1, 2, or 3.
Initially RadioButton3.Visible is set to False at design time. It becomes visible if the user selects to start the game.
We kick the whole thing off in Form.Load. I declared a Form level variable to keep track of what page we are on, PageNum.
I have only set properties in the pgX subs. All the action is in the submit button. The first thing is to find which radio button is selected. The GetSelectedRadioButton returns the selected button or Nothing. You have to pass Me (which refers to the Form, the class where the code is running) as the container. Often radio buttons are found in a GroupBox or other container control so this allows for that.
You will need to write the code for pg5, pg6, pg7, pg8, and pg9. Also add Case 5, Case 6, Case 7, Case 8, and Case 9 to the submit button.
Private PageNum As Integer
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
pgMain()
End Sub
Private Sub pgMain()
lblMain.Text = "Make a selection and click Submit"
RadioButton1.Text = "start the game"
RadioButton2.Text = "quit the game"
End Sub
Private Sub btnSubmit_Click(sender As Object, e As EventArgs) Handles btnSubmit.Click
Dim rb As RadioButton = GetSelectedRadioButton(Me)
If rb IsNot Nothing Then
Dim Name = rb.Name
Select Case PageNum
Case 0
If Name = "RadioButton1" Then
pg1()
ElseIf Name = "RadioButton2" Then
Close()
End If
Case 1
If Name = "RadioButton1" Then
MsgBox("Front door") '
pg2()
ElseIf Name = "RadioButton2" Then
MsgBox("backdoor")
pg3()
ElseIf Name = "RadioButton3" Then
gameOver("You were mauled by wolves")
End If
Case 2
If Name = "RadioButton1" Then
pg5() ' They went to the chest
ElseIf Name = "RadioButton2" Then
pg6() ' User went to the bookshelf
ElseIf Name = "RadioButton3" Then
pg7() ' User went to the cauldron
End If
Case 3
If Name = "RadioButton1" Then
MsgBox("Infected Part")
pg8()
ElseIf Name = "RadioButton2" Then
MsgBox("Milk")
pg9()
ElseIf Name = "RadioButton3" Then
gameOver("You injected yourself with viper venom.")
End If
End Select
Else
MessageBox.Show("Please make a selection.")
End If
End Sub
Public Function GetSelectedRadioButton(Container As Control) As RadioButton
Dim rb = Container.Controls.OfType(Of RadioButton)().FirstOrDefault(Function(r) r.Checked = True)
Return rb
End Function
Private Sub pg1() ' User picks a starting option
PageNum = 1
lblTitle.Text = "You spot a secret magical lair do you"
RadioButton1.Text = "Enter the lair through the front door"
RadioButton2.Text = "Enter the lair through the back door"
RadioButton3.Visible = True 'Set to False at design time
RadioButton3.Text = "Wait untill midnight to enter the lair."
End Sub
Private Sub pg2() ' User entered through the front door.
PageNum = 2
lblTitle.Text = "You see a chest, a bookself, and a cauldron"
RadioButton1.Text = "Go to the chest"
RadioButton2.Text = "Go to the bookshelf"
RadioButton3.Text = "Go to the cauldron"
End Sub
Private Sub pg3()
PageNum = 3
lblTitle.Text = "You were splashed with a poison spell do you"
RadioButton1.Text = "Cut off the infected part"
RadioButton2.Text = "Drink a bucket of milk"
RadioButton3.Text = "Inject yourself with some sort of medical syringe"
End Sub
Private Sub gameOver(DeathMessage As String)
lblTitle.Text = "Game Over!"
lblMain.Text = DeathMessage
RadioButton1.Visible = False
RadioButton2.Visible = False
RadioButton3.Visible = False
btnSubmit.Visible = False
End Sub

How to make cell readonly if the second cell is empty

The user should not be able to input a qty where the unit is empty in the datagridview.
To make it clear, I want to make the cell readonly = true if unit column is empty.
The colUOM4 is the name of the column that if the cell of this column is empty the olNewQty2 cell will be readonly.
I tried this code but it didn't work
Public Sub UnitEmpty()
For i As Integer = 0 To dgvCount.RowCount - 1
If dgvCount.Rows(i).Cells("colUOM4").Value Is Nothing Then
MessageBox.Show("It worked!")
dgvCount.Rows(i).Cells("colNewQty2").ReadOnly = True
Else
MessageBox.Show("Nothing happened!")
Exit For
End If
Next
End Sub
I'd recommend not using a loop because that will only set the state when you execute it and not react to any changes. I'd suggest working at the row and cell level, i.e. set the default state when a row is added and then react when a specific cell changes, e.g.
Private Sub DataGridView1_RowsAdded(sender As Object, e As DataGridViewRowsAddedEventArgs) Handles DataGridView1.RowsAdded
For i = e.RowIndex To e.RowIndex + e.RowCount - 1
'Make the first cell in each new row read-only by default.
DataGridView1(0, i).ReadOnly = True
Next
End Sub
Private Sub DataGridView1_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
'Check whether the change is in the second column.
If e.RowIndex >= 0 AndAlso e.ColumnIndex = 1 Then
Dim row = DataGridView1.Rows(e.RowIndex)
'Make the first cell in the row read-only if and only if the second cell is empty.
row.Cells(0).ReadOnly = (row.Cells(1).Value Is Nothing)
End If
End Sub

How to delete blank DataGridView Row on Load in VB.Net

I have a DataGridView that is bound by a datasource in VB.net Windows forms application. When I import my data into the DataGrid I want any blank or null fields to be colored in red until the user inputs data. I’ve already accomplished this but I have a slight issue. When the user adds a new blank row to the DataGrid and doesn’t fill in any data, that newly formed row on load up will be completely colored in red, instead I want to delete this newly generated row on load. This is how I’ve gone about doing this, but I haven’t been successful. I greatly appreciate any help or suggestions you may offer.
Private Sub DataGridView1_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles DataGridView1.CellFormatting
'Created a Boolean flag if empty
Dim empty as Boolean = True
Dim cellString = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
If cellString Is Nothing OrElse IsDBNull(cellString) OrElse cellString.ToString = String.Empty OrElse String.IsNullOrWhiteSpace(cellString) = True Then
empty = True
Else
empty = False
End If
'End If
'create variable assigned the rowindex of the last row of the DataGridView
Dim lastRow As String = DataGridView1.Rows(DataGridView1.RowCount - 1).Cells(0).Value
If (e.ColumnIndex = 0 OrElse e.ColumnIndex = 1 OrElse e.ColumnIndex = 2) Then
If empty = False Then
'If row is not empty then allow the newly generated row on load
DataGridView1.AllowUserToAddRows = true
Else
If empty = True AndAlso e.RowIndex = lastRow Then
'If row is empty and it’s the last row then prevent the row from being added to ‘the datagridview
DataGridView1.AllowUserToAddRows = False
Else If empty = True AndAlso e.RowIndex <> lastRow Then
'the row is empty and not the last row then paint the cell red
DataGridView1.Item(e.ColumnIndex, e.RowIndex).Style.BackColor = Color.Red
End If
End If
End If
End Sub

Disabling buttons one at a time

My partner and I are trying to figure out how to disable a button one at a time. We're making a program in Visual Studio Express 2012 that will disable a button once it is typed in a textbox. For example, we have five letters placed seperately on five different buttons If we were to put the letter "D" on the textbox, the button that contains that specific letter will be disabled. We're using the code
If e.KeyCode = Keys.D Then
Button1.Enabled = False
End If
Now that works, BUT if there were two or more buttons that has the same letters, all of them disables because then the code will be :
If e.KeyCode = Keys.D Then
Button1.Enabled = False
End If
If e.KeyCode = Keys.D Then
Button2.Enabled = False
End If
My problem would be in what way could I distinguish those buttons that has the same letter from one another so that when I type the letter on a textbox, only one button disables and when I type it in again, another button containing the same letter disables. Thanks!
Assuming all of the buttons are not in child panels:
If e.KeyCode = Keys.D Then
For Each b As Button In Me.Controls.OfType(Of Button)()
If b.Text.Contains("D") AndAlso b.Enabled Then
b.Enabled = False
Exit For
End If
Next
End If
This will recursively iterate all controls on the form looking for buttons and disable them based on the characters and number of characters entered into the textbox:
Private Sub textBox1_TextChanged(sender As Object, e As System.EventArgs)
Dim text As String = TryCast(sender, TextBox).Text.ToLower()
For Each b As Button In GetAllButtons(Me)
b.Enabled = True
Next
For Each c As Char In text
Dim count As Integer = text.Count(Function(cc) cc = c)
For i As Integer = 0 To count - 1
For Each b As Button In GetAllButtons(Me).Where(Function(x) x.Text.ToLower().Contains(c.ToString())).Take(count).ToList()
b.Enabled = False
Next
Next
Next
End Sub
Private Function GetAllButtons(control As Control) As List(Of Button)
Dim allButtons As New List(Of Button)()
If control.HasChildren Then
For Each c As Control In control.Controls
allButtons.AddRange(GetAllButtons(c))
Next
ElseIf TypeOf control Is Button Then
allButtons.Add(TryCast(control, Button))
End If
Return allButtons
End Function