returning a button from a function VB.net - vb.net

In my program I have to reference different dynamically created buttons and they are stored in an array of records. Depending on what FieldShow is equal to, one of three FlowLayoutPanels are visible, which contain the buttons.
Private Function GetFields(i As Integer) As LoadingTemplate
Dim TempFields As LoadingTemplate
If FieldShow = 0 Then
TempFields.B = Study(i)
ElseIf FieldShow = 1 Then
TempFields.B = Task(i)
ElseIf FieldShow = 2 Then
TempFields.B = Note(i)
End If
Return TempFields
End Function
TempFields.B.RefBtn, if used here, then shows the button that is being returned, But if elsewhere I put
GetFields(x).B.RefBtn
with an appropriate value for X, it sometimes doesn't return things. Is there an easier way of doing this?
Thanks,
Henry

Related

How can I improve this iterative function?

I am trying to simplify this function which is similar from
Function Snake_makestep()
maincar.Location = locate(xpos, ypos)
car0.Location = locate(posx(0), posy(0))
car1.Location = locate(posx(1), posy(1))
If car2.Visible = True Then
car2.Location = locate(posx(2), posy(2))
End If
If car3.Visible = True Then
car3.Location = locate(posx(3), posy(3))
End If
If car4.Visible = True Then
car4.Location = locate(posx(4), posy(4))
End If
To
If car30.Visible = True Then
car30.Location = locate(posx(30), posy(30))
End If
End Function
I'm not sure If I can/how to use Controls.Find solution within this function. Any help?
To answer the question as asked:
For i = 2 To 30
Dim car = Controls("car" & i)
If car.Visible Then
car.Location = locate(posx(i), posy(i))
End If
Next
Visible and Location are both members of the Control class so it doesn't matter what type of control those car variables are.
Note that this assumes that all controls are on the form itself. If they are in a different parent container, you'd need to use the Controls collection of that container.
Also, I have started i at 2 there, so you'd still need the explicit code for car0 and car1. If they are always visible then you could start the loop at 0 and it would still work, saving you those two lines of code as well.

VB 2-Dimensional Array Item comparison to image

Why does the messagebox show "False"?
Dim images(4, 4) As Image
For rows = 0 To 4
For columns = 0 To 4
images(rows, columns) = My.Resources.kaboom
Next
Next
MessageBox.Show(images(3, 3).Equals(My.Resources.kaboom))
If you look at the code behind the kaboom property, you will see it creates a new object every time.
'''<summary>
''' Looks up a localized resource of type System.Drawing.Bitmap.
'''</summary>
Friend ReadOnly Property kaboom() As System.Drawing.Bitmap
Get
Dim obj As Object = ResourceManager.GetObject("kaboom", resourceCulture)
Return CType(obj,System.Drawing.Bitmap)
End Get
End Property
If you keep a reference to one object, it will be equal to true. It might also be faster since it doesn't need to create a new object.
Dim kaboom As Image = My.Resources.kaboom
Dim images(4, 4) As Image
For rows = 0 To 4
For columns = 0 To 4
images(rows, columns) = kaboom
Next
Next
MessageBox.Show(images(3, 3).Equals(kaboom))
Maybe you are already planning on doing this but here is a suggestion. If you are creating some sort of game, separate the display from the game logic. This mean, save the type of tile instead of the image and compare that. Later, you can add a bunch of different properties to a tile.
Const TYPE_KABOOM As Integer = 1
Dim tileType(4, 4) As Integer
For rows = 0 To 4
For columns = 0 To 4
tileType(rows, columns) = TYPE_KABOOM
Next
Next
MessageBox.Show(tileType(3, 3).Equals(TYPE_KABOOM))

Access VBA Public Function - Variable for Control and Field?

I want to set up a public function like the following:
(A)
Public Function CheckYNField(chkControl As Control, chkField As String)
If chkField = "Y" Then
chkControl = -1
ElseIf chkField = "N" Then
chkControl = 0
Else: chkControl = 0
End If
End Function
(B)
Public Function CheckYNFlipper(chkControl As Control, chkField As String)
If chkField = "Y" Then
chkField = "N"
chkControl = 0
ElseIf chkField = "N" Then
chkField = "Y"
chkControl = -1
Else: chkField = "Y"
chkControl = -1
End If
End Function
The reason for this is, that I have a form, which has an underlying SQL table. I have no control over the data, but I must represent it, for the ability to maintain it. I have 10 fields, in the underlying table, which have a Y or N as their values. The data types are actually nvarchar(10). At the same time, I have to show these fields as checkbox controls, on the form, for ease of use.
The above code, is an attempt I am making to A - set the checkbox control to align with the current value in the table--> -1 = Y and 0 = N, and to B - update the table value, and switch the check box to checked or unchecked, from what it was, to the opposite, based on the onclick event of that control.
I want to make chkField and chkControl variables to the public function, that would be the table-field, and the form-control. I can't seem to get the right syntax, and was hoping someone might have clarification on how to do this.
for the form load and current, I tried this:
CheckYNField Forms("frmFormNameA").Controls(chkCheckNameA), tblTableName.FieldA
for the on click, I tried this:
CheckYNFlipper Forms("frmFormNameA").Controls(chkCheckNameA), tblTableName.FieldA
I've tried some other methods, but doesn't seem to be working. I'm doing something wrong, but I can't tell what. Appreciate any tips!
Edit/Update:
I tried Kostas K.'s solution, abandoning the idea of making a public functions with parameters for the fields and controls. I put the following, on load and on current:
With Me
If .txtfieldboundtablefieldA.Value = "Y" Then
.unboundchkA.Value = True
ElseIf .txtfieldboundtablefieldA.Value = "N" Then
.unboundchkA.Value = False
Else: .unboundchkA.Value = False
End If
End With
This is on a continuous form, so that it can show like a giant grid. There are the identifying bound field controls, and then a series of these checkboxes, to display the Y/N true/false status of each of these particular fields. I can't bound the checkboxes to the fields, because it changes the field value in the table to -1 or 0, and we need it to stay Y or N. I added a bound text field, to hold the table/field value for each row (hence the call to a text box control in the above revised code). The checkbox is unbound, and is there to display the field value, and allow the user to check and uncheck, so I can use on-click code to change the table field value between Y and N.
The above code is not seeming to show the correct checkbox value for each bound text field, based on each row. It shows based on the row that currently has focus. If I click on a row, where the table field is Y, all rows checkboxes on the form show true. If I move to a row, where the table field is N, all checkboxes for all rows change to false. I am struggling to just initially get 1 checkbox to show accurately, on every row of the continuous form, based on every record in the table. This is a small table, like 30 records. I really didn't think it would be so difficult to present this the way we need to.
Any ideas, how I could better do this?
Edit:
Set the Control Source of the checkbox to:
= IIf([YourYesNoField] = "Y", -1, 0)
In order to update when clicked:
Private Sub chkCheckNameA_Click()
Dim yesNo As String
yesNo = IIf(Me.chkCheckNameA.Value = 0, "Y", "N") 'reverse value
CurrentDb.Execute "Update [YourTable] SET [YourYesNoField]='" & yesNo & "' WHERE [ID]=" & Me![ID], dbFailOnError
Me.Requery
End Sub
You could try something this.
Check the Y/N field and assign the function's boolean return value to the checkbox (A).
On the checkbox click event, check its value and update the Y/N field (B).
'Form Load
Private Sub Form_Load()
With Me
.chkCheckNameA.Value = CheckYNField(![FieldA])
End With
End Sub
'Click
Private Sub chkCheckNameA_Click()
With Me
![FieldA] = IIf(.chkCheckNameA.Value = 0, "N", "Y")
End With
End Sub
'True returns -1, False returns 0
Private Function CheckYNField(ByVal chkField As String) As Boolean
CheckYNField = (chkField = "Y")
End Function
chkControl is a Control, so you need to access a property of that control. Try changing your code to:
Public Function CheckYNField(chkControl As Control, chkField As String)
If chkField = "Y" Then
chkControl.Value = -1
ElseIf chkField = "N" Then
chkControl.Value = 0
Else: chkControl.Value = 0
End If
End Function
and then the same idea in your other function.

How to enable/disable button with a function

I have a problem with my university project
It's a little game, 6 buttons for each players and 2 players so 12 buttons
There is number in each buttons, if a player has his 6 buttons at 0, he can't play
I have try some Public Function and i'm actually working with a very simple one but i think this is not the problem
My function is here
And in my form, the problem is here, i've tried many things but i don't know how do to that ... I read my lesson and I'm searching on the internet, i have no idea ..
If possible is True you don't re-enable the button.
You can simplify things.
Public Function PeutJouer(ByVal joueur As Integer) As Boolean
Dim sum As Integer
Dim start As Integer = (joueur - 1) * 7
For i As Integer = start To start + 5
sum += tableau(i)
Next
Return sum <> 0
End Function
Then
Btn1P1.Enabled = PeutJouer(1)
Did you show all the relevant code? You are declaring Dim tableau(12) As Integer but the array is never filled with values. Probably tableau should be declared at the form level and not locally in this function. If you already have both, remove the local declaration, because it hides the one at form level. You also need to return the result from the function. I don't see this in your function.
Note that this
If x <> 0 Then
booleanVariable = True
Else
booleanVariable = True
End If
can be simplified to
booleanVariable = x <> 0
i.e., the condition is an expression yielding the Boolean result True or False already and you can use this value directly. When working with numeric values you don't write If x + y = 1 Then r = 1 Else If x + y = 2 Then r = 2 .... You simply write r = x + y.

change color of every datagridview row containing a certain value

Is this possible? what i'm currently doing is just looping through each row to change the color, but this is very slow since i'm also running a query and based on the results I change the color. Here's an example
Part No | Other Columns
-----------------------
Part A | 123456
Part B | 123456
Part C | 123456
Part A | 123456
Part A | 123456
My query's where is Where Part_No = 'Part A', with my current method I would just be running the same query 3 times. What I want to do is get the distinct Values on the first column, check those in the query and change the color of the rows containing that value.
answered here: How to change row color in datagridview?
===
I was just investigating this issue (so I know this question was published almost 3 years ago, but maybe it will help someone... ) but it seems that a better option is to place the code inside the RowPrePaint event so that you don't have to traverse every row, only those that get painted (so it will perform much better on large amount of data:
Attach to the event
this.dataGridView1.RowPrePaint
+= new System.Windows.Forms.DataGridViewRowPrePaintEventHandler(
this.dataGridView1_RowPrePaint);
The event code
private void dataGridView1_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
if (Convert.ToInt32(dataGridView1.Rows[e.RowIndex].Cells[7].Text) < Convert.ToInt32(dataGridView1.Rows[e.RowIndex]..Cells[10].Text))
{
dataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Beige;
}
}
An economical way is to use the CellFormatting event. This will fire when that cell is displayed the first time. It will only fire for the visible rows so it should be faster.
Then I loop through the grid view to do something like update the data of all colored rows
If the data comes from db (the OP mentions a query) you ought to be acting on the data like the datasource. The DGV is just the user's view of the data. Rather than acting on rows of a certain color, act on the part number or whatever determines the color. You could also create a view of the records with this or that part number and act/loop on that to simplify the process.
Since the data can change, you'll want to handle 2 events: CellFormatting and CellValueChanged
Private Sub dgv1_CellFormatting(...) Handles dgv1.CellFormatting
' default start up color
If e.ColumnIndex = 3 Then
e.FormattingApplied = ColorMyRow(e.RowIndex, e.ColumnIndex)
Else
e.FormattingApplied = False
End If
End Sub
Private Sub dgv1_CellValueChanged(...) Handles dgv1.CellValueChanged
' if the target cell changes, update
If e.ColumnIndex = 3 Then
ColorMyRow(e.ColumnIndex, e.RowIndex)
End If
End Sub
' DRY
Private Function ColorMyRow(rowIndex As Int32, colIndex As Int32) As Boolean
Dim bass As Color = Color.PeachPuff
Dim pike As Color = Color.SeaShell
Dim salmon As Color = Color.Salmon
Select Case dgv1.Rows(rowIndex).Cells(colIndex).Value.ToString
Case "Bass"
dgv1.Rows(rowIndex).DefaultCellStyle.BackColor = bass
Return True
Case "Pike"
dgv1.Rows(rowIndex).DefaultCellStyle.BackColor = pike
Return True
Case "Salmon"
dgv1.Rows(rowIndex).DefaultCellStyle.BackColor = salmon
Return True
End Select
Return False
End Function
The color will be updated whether a) the user edits the cell, b) you change a cell value ( dgv1.Rows(0).Cells(3).Value = "Mermaid" ) or c) you change the datasource ( dtParts.Rows(0)(3) = "Pike").
Finally, rather then trying to loop on the blue rows, you can query the DataSource, in this case, a DataTable:
Dim bassRows = dtSample.Select("Fish = 'Bass'")
For Each dr As DataRow In bassRows
dr("Fish") = "Pike"
Next
The color will automagically change.