This is my first question in this community and I'd like some help with a school project I am doing.
I am implementing a turn system where every time you select a method to score a variable called turn increases by one so that the appropriate label is changed to the points you got that turn.
This is an example of the Ones option to score which checks all the dice and adds up all the dice which have the value one, when the Ones button is pressed it should update the current turn with the points gained. At the moment it only updates the first turns score. The second and third images are of the changes I tried making which don't work.
[Ones][1]
[Ones changed][2]
[Ones error][3]
```
Private Sub btnOnes_Click(sender As Object, e As EventArgs) Handles btnOnes.Click
Dim Nums(4) As Integer
Nums(0) = RandomNum1
Nums(1) = RandomNum2
Nums(2) = RandomNum3
Nums(3) = RandomNum4
Nums(4) = RandomNum5
For i = 0 To 4
If Nums(i) = 1 Then
OnesScore += 1
End If
Next
lblTurnValue1.Text = OnesScore
Turn += 1
btnOnes.Enabled = False
End Sub
Private Sub btnOnes_Click(sender As Object, e As EventArgs) Handles btnOnes.Click
Dim Nums(4) As Integer
Nums(0) = RandomNum1
Nums(1) = RandomNum2
Nums(2) = RandomNum3
Nums(3) = RandomNum4
Nums(4) = RandomNum5
For i = 0 To 4
If Nums(i) = 1 Then
OnesScore += 1
End If
Next
lblTurnValue1(Turn).Text = OnesScore
Turn += 1
btnOnes.Enabled = False
End Sub
Another problem I have been having is automatically updating labels as I want to make a Newbie mode for my Yahtzee game which displays the numbers beside each option to score so you know what score you are going to get before you choose.
I can't use the Ones button for clicking to represent the score because it's used for scoring the points and whenever I try double click on the label to show its code in Visual Studio it only updates in game when the person clicks the number to show their score which is not what I desire.
[Ones label][4]
Private Sub lblOnes_Click(sender As Object, e As EventArgs) Handles lblOnes.Click
lblOnes.Text = OnesScore
End Sub
In short I want to learn how to use variables within names of objects to allow for the right one to be chosen and how to update labels automatically instead of having to click them. Any resources you can provide to further my understanding of VB.NET is really helpful.
Thanks.
[1]: https://i.stack.imgur.com/zUQM6.png
[2]: https://i.stack.imgur.com/c5nJe.png
[3]: https://i.stack.imgur.com/Y3gUE.png
[4]: https://i.stack.imgur.com/BnwZ8.png
I want to get length of each line in multiline textbox and show in another textbox like 3/12
and check if each line more than 36 Characters then forecolor of the textbox indicating length of lines should be red.
I wrote a cod for that but doesn't work very well.
how can i achive that? thank you all.
My cod is:
Private Sub Texttb_TextChanged(sender As Object, e As EventArgs) Handles Texttb.TextChanged
TextBox2.Clear()
For Each lin As String In Texttb.Lines
TextBox2.AppendText(lin.Length & "/")
If lin.Length > 38 Then
TextBox2.ForeColor = Color.Red
ElseIf lin.Length < 38 Then
TextBox2.ForeColor = Color.Black
End If
Next
If you only care about whether any lines are too long then just use Any:
TextBox2.ForeColor = If(TextBox1.Lines.Any(Function(line) line.Length > MAX_LINE_LENGTH),
Color.Red,
Color.Black)
EDIT:
Based on the full problem description that I managed to tease out, this is probably the way to go:
Const MAX_LINE_LENGTH = 38
Dim lineLengths = TextBox1.Lines.Select(Function(line) line.Length).ToArray()
With TextBox2
.Text = String.Join("/", lineLengths)
.ForeColor = If(lineLengths.Any(Function(n) n > MAX_LINE_LENGTH),
Color.Red,
SystemColors.ControlText)
End With
The purpose of my assignment is to create a calculator that uses number inputs from two textboxes. The calculator works when only dealing with a single textbox(boxequation1) but I need it to accept another input from the other textbox(boxequation2). Is there any way to input a number into boxequation1, select an operation, input a number into boxquation2, and then compute the result?
Public Class Form1
Private Sub ButtonClickMethod(sender As Object, e As EventArgs) Handles num0.Click, num1.Click, num2.Click, num3.Click, num4.Click, num5.Click, num6.Click, num7.Click, num8.Click, num9.Click, opdivision.Click, opmultiply.Click, opdecimal.Click, opclear.Click, opminus.Click, opadd.Click, opequal.Click
Dim button As Button = CType(sender, Button)
If button.Name = "num1" Then
boxequation1.Text = boxequation1.Text + "1"
End If
If button.Name = "num2" Then
boxequation1.Text = boxequation1.Text + "2"
End If
If button.Name = "num3" Then
boxequation1.Text = boxequation1.Text + "3"
End If
If button.Name = "num4" Then
boxequation1.Text = boxequation1.Text + "4"
End If
If button.Name = "num5" Then
boxequation1.Text = boxequation1.Text + "5"
End If
If button.Name = "num6" Then
boxequation1.Text = boxequation1.Text + "6"
End If
If button.Name = "num7" Then
boxequation1.Text = boxequation1.Text + "7"
End If
If button.Name = "num8" Then
boxequation1.Text = boxequation1.Text + "8"
End If
If button.Name = "num9" Then
boxequation1.Text = boxequation1.Text + "9"
End If
If button.Name = "num0" Then
boxequation1.Text = boxequation1.Text + "0"
End If
If button.Name = "opdecimal" Then
boxequation1.Text = boxequation1.Text + "."
End If
If button.Name = "opequal" Then
Dim equation1 As String = boxequation1.Text
Dim equation2 As String = boxequation2.Text
Dim result = New DataTable().Compute(equation1, Nothing)
boxresult.Text = result
End If
If button.Name = "opminus" Then
boxequation1.Text = boxequation1.Text + "-"
boxoperator.Text = boxoperator.Text + "-"
End If
If button.Name = "opmultiply" Then
boxequation1.Text = boxequation1.Text + "*"
boxoperator.Text = boxoperator.Text + "x"
End If
If button.Name = "opdivision" Then
boxequation1.Text = boxequation1.Text + "/"
boxoperator.Text = boxoperator.Text + "÷"
End If
If button.Name = "opadd" Then
boxequation1.Text = boxequation1.Text + "+"
boxoperator.Text = boxoperator.Text + "+"
End If
If button.Name = "opclear" Then
boxequation1.Clear()
boxoperator.Clear()
boxresult.Clear()
End If
End Sub
Private Sub opbackspace_Click(sender As Object, e As EventArgs) Handles opbackspace.Click
boxequation1.Text = boxequation1.Text.Remove(boxequation1.Text.Count - 1)
End Sub
End Class
I'm having a lot of fun with your homework.
Now... I'm not sure how I should do to help you. I initially wanted to code it and obfuscate parts of the code so you could check at what's clear and understand the rest by yourself, but on the other hand I have no idea if that would really help. I though that maybe you would do better with more explanations.
So I re-coded the whole thing, loosely based on what you posted earlier.
I heavily commented my work so you will be able to understand why I did things that war, but really you can and should ask me questions about everything which isn't cristal clear in this.
And, once you feel more confident about it, you should scrap my work and code it again, but from scratch this time. You're doing this to learn, after all!
Here what it looks like:
.-.-.-.-.-.-.-.-.
Here's a very cusomized New() Sub. It's not how I coded it; I needed only the 3 first lines of this monstruosity, but I wanted you to see the rest of it because that's how I set up my controls in the designer.
You should set up your controls names, texts and tags in the designer, really. This part really is here only because it was easier to show you these settings this way.
Private Sub New()
InitializeComponent()
_currentTextBox = Number1TextBox
_locked = False
ResultsTextBox.TextAlign = HorizontalAlignment.Center
ResultsTextBox.Text = "SUPER DUPER CALCULATOR"
For Each textBox As System.Windows.Forms.TextBox In {ResultsTextBox, Number1TextBox, Number2TextBox}
'This prevent the user from writing in your textboxes instead of using the buttons.
textBox.ReadOnly = True
Next
'I used the .Text and .Tag properties to make the code easier to manage. Observe:
num0Button.Text = "0"
num1Button.Text = "1"
num2Button.Text = "2"
num3Button.Text = "3"
'...
num9Button.Text = "9"
opAddButton.Text = "+"
opMinusButton.Text = "-"
opMultiplyButton.Text = "x"
opDivideButton.Text = "÷"
For Each button As Button In {num1Button, num2Button, num3Button, num4Button, num5Button, num6Button, num7Button, num8Button, num9Button}
button.Tag = "number"
Next
For Each button As Button In {opAddButton, opMinusButton, opMultiplyButton, opDivideButton}
button.Tag = "operation"
Next
num0Button.Tag = "numberZero"
opDecimalButton.Tag = "decimal"
opBackspaceButton.Tag = "backspace"
opEqualButton.Tag = "equal"
End Sub
And now for the real code: the subs that your class will need and use:
'Class variables are useful to remember informations which will be useful at several unrelated places.
'_currentTextBox is a pointer to the TextBox which is currently being filled
Private _currentTextBox As System.Windows.Forms.TextBox = Number1TextBox
'_Llocked will prevent the user from messing with the calculator after he pressed "equal"
Private _locked As Boolean = False
'I didn't like this idea but I went with it since it was your initial method.
'Notice how shoter this iteration of your idea is. Strive to shorten your code while making your variable names much easier to read.
'For real, make sure your variables are aptly names. Every control should be identified as such (the button num0 should be names num0Button for example)
'Code is hard enough to read without making it sibylline
Private Sub ButtonClickMethod(sender As Object, e As EventArgs) Handles num0Button.Click, num1Button.Click, num2Button.Click, num3Button.Click, num4Button.Click, num5Button.Click, num6Button.Click, num7Button.Click, num8Button.Click, num9Button.Click, opDivideButton.Click, opMultiplyButton.Click, opDecimalButton.Click, opClearButton.Click, opMinusButton.Click, opAddButton.Click, opEqualButton.Click, opBackspaceButton.Click
'DirectCast is more strick than CType. For this operation, it doesn't really make a difference, but that's the one you want anyway.
Dim button As System.Windows.Forms.Button = DirectCast(sender, System.Windows.Forms.Button)
'The boolean _locked prevent the user from messing with your beautiful calculator.
If Not _locked Then
'This is where the .Tag property save lifes. All numbers (but zero) are "number" now. BAM!
Select Case button.Tag.ToString
Case "number"
_currentTextBox.Text += button.Text
Case "numberZero"
'You don't want your clever teacher to try to divide by zero, or create a number with 5 zeros before the actual number.
'This is how you can do this.
If _currentTextBox.Text.Length > 0 Then
_currentTextBox.Text += button.Text
End If
Case "decimal"
If _currentTextBox.Text.Length > 0 AndAlso Not _currentTextBox.Text.Contains(".") Then
_currentTextBox.Text += button.Text
End If
Case "operation"
ResetOperationTextBoxes()
'here's a nifty visual cue about which operation has been selected. It's not really important.
button.BackColor = Color.LightSalmon
'This label will be used to Calculate() the operation. It's important!
OpLabel.Text = button.Text
Case "backspace"
If _currentTextBox.Text.Length > 0 Then
_currentTextBox.Text = _currentTextBox.Text.Substring(0, _currentTextBox.Text.Length - 1)
End If
Case "equal"
'I could have put the code here instead of making another sub, but I didn't.
'There are two valid reasons for this.
'1- This code might be useful on it's own later: maybe something else will Calculate() or LockCalculator or ResetCalculator later.
'2- try to avoid blobs of code. A big and complex sub is easier to understand when it's divided between several clean and clear smaller subs.
' (of course, you cannot always subdivise Subs. Use common sense)
Calculate()
End Select
End If
'This check is all alone because I want it to work even if the calculator is locked.
If button.Tag.ToString = "clear" Then
ResetCalculator()
End If
End Sub
Private Sub Calculate()
'Always make checks to make sure that things are going the way you think they should be going.
'for example, here I want to have 2 numbers and an operation, er else I'll just ignore this click.
If Number1TextBox.Text.Length > 0 AndAlso Number2TextBox.Text.Length > 0 And OpLabel.Text <> "?" Then
'If the user could mess with the textboxes, i would have to make further checks to avoid crashes, but I already force the user to use only numbers se we're cool.
Dim number1 As Double = Convert.ToDouble(Number1TextBox.Text)
Dim number2 As Double = Convert.ToDouble(Number2TextBox.Text)
Dim result As Double
Select Case OpLabel.Text
Case "+"
result = number1 + number2
Case "-"
result = number1 - number2
Case "x"
result = number1 * number2
Case "÷"
result = number1 / number2
End Select
ResultsTextBox.TextAlign = HorizontalAlignment.Right
ResultsTextBox.Text = result.ToString
LockCalculator(True)
End If
End Sub
'By using a boolean to signify to this Sub if I want to lock or unlock things, I make it easier to automatize this operation (and I have only one Sub instead of two).
Private Sub LockCalculator(ByVal isLocked As Boolean)
_locked = isLocked
'I'm kinda cheating here: I put the calculator inside a GroupBox just so I could be lazier and do this.
'Being lazy is great for a coder, as long as you think ahead (and avoid being a nuisance to yourself when you'll come back to this code and weep).
For Each control As System.Windows.Forms.Control In CalculatorGroupBox.Controls
control.Enabled = Not isLocked
Next
'Except that I want this button to always be available, so I enable it. This operation wouldn't be necessary if isLocked is True, but checking for that is longer than just doing it.
opClearButton.Enabled = True
End Sub
Private Sub ResetCalculator()
ResetNumberTextBoxes()
ResetOperationTextBoxes()
LockCalculator(False)
_currentTextBox = Number1TextBox
End Sub
Private Sub ResetNumberTextBoxes()
For Each textBox As System.Windows.Forms.TextBox In {Number1TextBox, Number2TextBox}
textBox.Text = ""
Next
'Mea Culpa: I shouldn't had done a For Each for 2 elements like that. I did it anyway. Please don't call the Fun Police on me.
'Also, you can now guess that using For Each loops to set up controls is a work method I like. Some don't like that.
'There is about as many ways to code something as there are coders. You have to find your own, sure, but then you'll get hired somewhere
'and they will absolutely hate everything that you do that isn't done the way they like it. And they will be right. On a big project where
'several coders works, at the same time and for month and years, you have to find a common ground or else the code will become a nightmare
'to understand and maintain. Trust me: being able to adapt quickly to other's work methodology is a GREAT skill in this field of work.
ResultsTextBox.TextAlign = HorizontalAlignment.Center
ResultsTextBox.Text = "SUPER DUPER CALCULATOR"
End Sub
Private Sub ResetOperationTextBoxes()
For Each button As System.Windows.Forms.Button In {opAddButton, opMinusButton, opMultiplyButton, opDivideButton}
button.BackColor = DefaultBackColor
Next
OpLabel.Text = "?"
End Sub
'This sub is great. It uses the _currentTextBox as a pointer. Maybe you're not familiar with pointers, I don't know. The short explanation is this:
'A pointer is like a phone number. You can give your number to several people without "losing" it. And if they call you and tell you something, they
'are all speaking to the same person.
'_currentTextBox is a pointer which can point toward Number1TextBox or Number2TextBox.
'This Event makes it so when the user click on Number1TextBox or Number2TextBox, the pointer updates it's "phone number" to the right box,
'so later when we'll write we'll write in the last one which was clicked on.
Private Sub NumberTextBoxes_Click(sender As Object, e As EventArgs) Handles Number1TextBox.Click, Number2TextBox.Click
_currentTextBox = DirectCast(sender, System.Windows.Forms.TextBox)
End Sub
Here you go. I hope that you'll have as much fun with coding as I did!
Before I go to sleep now, here's a few things that I think that you should make an effort to improve on:
1 Name your controls with really, really obvious names. Nobody care that the names are long, we all use the intelliSense anyway. But anything that we cannot guess at a glance is not clear enough!
2 Same thing with your variables. Same for everything which has a name, in fact. If you show your work to a teammate and he's not able to guess which control you're speaking about just by it's name, it's not clear enough!
3 The rest you will learn as you persevere through understanding your friend, the computer.
4 You should turn on Explicit and Strict mode. It'll help you understand the type you're working with and how they interact. It'll reduce dramatically the risk of awful manipulations. In fact, as though the more experience a coder has, the less he'll need these options, the more experienced a coder is, the more likely he'll be to have those two little lines of code at the beginning of all his works...
Here's how I begin every page of VB code at home:
.-.-.-.-.-.-.-.-.
4 Ask questions! To me, to classmates, to teachers! Ask questions to everything that moves!
Good luck!
I'm new to "coding/programming". I'm trying to make a functional program - I call it "a point to pay". It's like those supermarket programs where they register the thing you are going to buy. So i need to create some labels to register products.
The code I have:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click ''When i click the button
If CantidadVer1.Text = 0 Then ''this verifies how many Labels i have created
CantidadVer1.Text = +1 ''this updates the verification
Dim lbl1 As New Label ''this creates the labels
lbl1.Size = New System.Drawing.Size(159, 23)
lbl1.Text = (Product.Text) ''product.text is a TextBox
lbl1.Location = New System.Drawing.Point(12, 80 + 20) '' i add 20 more everytime i create a label
Me.Controls.Add(lbl1)
ElseIf CantidadVer1.Text = 2 Then ''at this point it creates the label but "crashes" (It dosent work anymore)
CantidadVer1.Text = +1
Dim lbl2 As New Label
lbl2.Size = New System.Drawing.Size(159, 23)
lbl2.Text = (Product.Text)
lbl2.Location = New System.Drawing.Point(12, 80 + 40)
Me.Controls.Add(lbl2)
ElseIf CantidadVer1.Text = 2 Then
CantidadVer1.Text = +1
Dim lbl3 As New Label
lbl3.Size = New System.Drawing.Size(159, 23)
lbl3.Text = (Product.Text)
lbl3.Location = New System.Drawing.Point(12, 80 + 60)
Me.Controls.Add(lbl3)
ElseIf CantidadVer1.Text = 3 Then
CantidadVer1.Text = +1
Dim lbl4 As New Label
lbl4.Size = New System.Drawing.Size(159, 23)
lbl4.Text = (Product.Text)
lbl4.Location = New System.Drawing.Point(12, 80 + 80)
Me.Controls.Add(lbl4)
ElseIf CantidadVer1.Text = 4 Then
CantidadVer1.Text = +1
Dim lbl4 As New Label
lbl4.Size = New System.Drawing.Size(159, 23)
lbl4.Text = (Product.Text)
lbl4.Location = New System.Drawing.Point(12, 80 + 100)
Me.Controls.Add(lbl4)
End If
End Sub
So I execute it and then it creates 2 labels and then crashes.
It is supposed to create 5 labels .
Is there an easier way to create multiple labels without making the program crash?
In your code I only see one label created every time. I don't think the code crashes. Remember in an IF block, if the condition is met in the first part, it skips all subsequent ElseIf conditions.
With a little research, you'll see that the best option would be to use a DataGridView instead of a bunch of labels. You could simply add a new row for each item. Lets say you have a datagridview named DGV_Product with 3 textbox columns for product, quantity and price:
Dim price as Double = 1.99
Dim product as String = "Apple"
Dim qty as integer = 3
DGV_Product.Rows.Add(New String() {product, Cstr(qty), CStr(price)})
That adds a row containing "Apple, 3, 1.99"
But if you insist on using labels, This would work better:
1) Set The following variable at a class level.
Dim lbl_pos as integer
2) In your form Load event handler set the value to 20 less than where you want your first label to appear:
lbl_pos = 80 ' gathered from your code
3) Then in your click event handler of the button you increment the new label's position by 20 before adding the new label.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
lbl_pos = lbl_pos + 20 'increment the position
Dim lbl as New Label
With lbl
.Text = "Your Text"
.Location = New Point(10,lbl_pos) '(left position, top position)
' And so Forth
End With
me.controls.add(lbl)
End Sub
With this approach you can add as many labels as you like without a bunch of If-ElseIf blocks.
I hope you rethink your approach and go with the DataGridView instead as it's much more practical and you can add as many rows as you like without hassle.
You have an error in your code .. The line
ElseIf CantidadVer1.Text = 2 Then ''at this point it creates the label but "crashes" (It dosent work anymore
should be
ElseIf CantidadVer1.Text = 1 Then ''at this point it creates the label but "crashes" (It dosent work anymore)
If you dont set the value for CantidadVer1 in the begining. Its value = "" not 0. so it will be the bug if you dont put 0 to the CantidadVer1.text
the first if maybe like this
If CantidadVer1.Text = "" OR CantidadVer1.Text = 0 Then
Your PTP is poorly designed. All the answers here are trying to solve your problem by looking based on what you've done.
But your model is kinda based on your what's in your view. For example, have you planned how you will retrieve all the added products ? The history is inside your view : good luck with that.
That's why I suggest to review your design. For example :
Use a List in your code behind to save your data. Your button_click should only do that (with some validations).
Use a repeater in your view. Bind that repeater to your List : and voila. Your repeater will take care of creating all the label corresponding to all the added products.
Hopefully this will make sense, but I am creating this 'board' type game where there is a die and twenty-eight labels, which I have made the labels into small squares and next to each other.
I need to figure out code which will automatically light up (change the BackColor) of the labels, based on the number generated by the die, which the player clicks on.
For example, when the player clicks the die a number is generated (1 - 6) and this is how many labels light up, and continues till all labels BackColor has changed to a different colour, e.g. green.
Code for die:
Private Sub imgDie_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles imgDie.Click
My.Computer.Audio.Play(My.Resources.Dice, AudioPlayMode.Background)
randomNumber = rand.Next(1, 7)
If randomNumber = 1 Then
imgDie.Image = My.Resources.Die_One
ElseIf randomNumber = 2 Then
imgDie.Image = My.Resources.Die_Two
ElseIf randomNumber = 3 Then
imgDie.Image = My.Resources.Die_Three
ElseIf randomNumber = 4 Then
imgDie.Image = My.Resources.Die_Four
ElseIf randomNumber = 5 Then
imgDie.Image = My.Resources.Die_Five
ElseIf randomNumber = 6 Then
imgDie.Image = My.Resources.Die_Six
End If
End Sub
So, what could I do to make sure the correct number of labels BackColor are changed? Would I need a function? Also, as the die is clicked numerous amount of times, labels are going to light up, so how do I get it so that those that haven't changed, are until all twenty-eight labels BackColor has changed?
I hope that this makes some sense?
The labels are named:
lblSquareOne, lblSquareTwo, lblSquareThree right through to lblSquareTwentyeight
Something like this might get you started:
Private Function ToggleLabels(ByVal NumberToDo As Integer) As Boolean
Dim R As New Random
Dim n As Integer
Dim count As Integer = 0
Dim lbl As Label
' in MY app, the labels would all be grouped (ALONE) on a panel
' so I could find them easily in its Controls Array
' I am also using the Label.Tag property to track it's state
' could also go by its BackColor
' do until we match the die count passed OR
' the new AllLitUp function tells us we are Done
Do Until (count = NumberToDo)
n = R.Next(0, 28) ' maxValue is exclusive
lbl = LabelsPanel.Controls(n)
' is this one already Lit?
If lbl.Tag = "FALSE" Then
' change the color
lbl.BackColor = TheLitColor
lbl.Tag = "TRUE" ' set indicator
count += 1 ' increase the count for this round
' dont need this here AND in the loop control
If AllLitUp() Then ' check for game over
Exit Do
End If
End If
Loop
' Return T/F is it Game Over
Return AllLitUp()
End Function
When you loop thru the labels to reset the color for a new game, be sure to set .Tag to "FALSE" (with the quotes).
Better would be LabelItem class which holds a reference to a label (which it could get itself when New) and a flag.
Then another class - LabelItems - to manage them. LabelItems could store 28 of them in a List(Of LabelItem). This would make managing individual labels easy (no need to loop thru an array) as well as 'global' things like a procedures to clear for a new game, get the score so far, add a Timer either for scoring or for Beat The Clock etc.