Function myFunction(ByVal degree1 As PictureBox) As PictureBox
degree1.Visible = True
degree1.Image = Image.FromFile("C:\Standard Pics\waiting3.gif")
degree1.Location = New Point(locationx, locationy)
degree1.Size = New Size(51, 51)
End Function
I'm very new to making functions in visual basic- anyway, I'm trying to make a function that makes several changes to a picturebox, but it gives me this "Argument not specified for parameter 'degree1' of 'Public Function myFunction(ByVal degree1 As PictureBox) As PictureBox'" error- any possible fixes?
Please try following:
Sub mySub(ByRef degree1 As PictureBox)
degree1.Visible = True
degree1.Image = Image.FromFile("C:\Standard Pics\waiting3.gif")
degree1.Location = New Point(locationx, locationy)
degree1.Size = New Size(51, 51)
End Sub
Note the ByRef part in Sub() signature - it means that you're directly operating over given PictureBox object. This is called "passing argument by reference". You can read more about it here. Oh, and I presume you have your locationx and locationy variables set somewhere in your code?
Related
I am trying to create a general function in VB.NET that can dynamically create a form object (label , button etc.) and this object can be pin the form or container .
My problem is i am unable to pass the control object type to the function when calling it.
Visual studio gives error.
Private Function AddnewObject(newObject As Integer, ContainerObject As Object, ByRef Objectn As Control) As System.Windows.Forms.Control`
ContainerObject.Controls.Add(Objectn)
Objectn.Top = 560 + (newObject * 27)
Objectn.Left = 100
Objectn.Text = Objectn.ToString & newObject.ToString
newObject += 1 ' useless in this context
Return Objectn
End Function
when trying to call it like this :
AddnewObject(concounter, TableLayoutPanel1, Label)
i get error
BC30109 'Label' is a class type and cannot be used as an expression.
I tried to change the type of objectn but can't figure the correct one/way to use
You can pass a type as parameter with generic type parameters (the (Of T) part in front of the normal parameter list). Normal Sub or Function parameters can be only values, not types (though they can be of type System.Type).
I suggest to change the function like this
Private conCounter As Integer = 1
Private Function AddNewControl(Of T As {Control, New})(controls As Control.ControlCollection) As T
Dim newControl As T = New T()
controls.Add(newControl)
With newControl
.Top = 560 + (conCounter * 27)
.Left = 100
.Name = GetType(T).Name & conCounter
End With
conCounter += 1
Return newControl
End Function
and to call it like this
Dim newControl = AddNewControl(Of Label)(TableLayoutPanel1.Controls)
Explanation:
The type of the control to be created is passed as generic type parameter. The type constraint {Control, New} ensures that only control types are passed and that they have a default constructor (which is always the case for Controls).
I am using concrete types instead of Object. Use Option Strict On to create better quality code.
Since not all controls used as container object inherit from ContainerControl (e.g., TableLayoutPanel does not), I have chosen to pass the ControlCollection of the container object to this function instead.
The counter needs not to be passed as parameter if it is in the same class (or module)
This function does return the new control as function value. If this is not required, you can also turn it into a Sub instead.
Private Sub AddNewControl(Of T As {Control, New})(controls As Control.ControlCollection)
Dim newControl As T = New T()
controls.Add(newControl)
With newControl
.Top = 560 + (conCounter * 27)
.Left = 100
.Name = GetType(T).Name & conCounter
End With
conCounter += 1
End Sub
And call with
AddNewControl(Of Label)(TableLayoutPanel1.Controls)
I'm new to vb.net. To be honest I've only been using it for a week or so. I've actually hit a wall when it comes to creating a Public Function for dynamically created buttons.
I've got a form in which I've got the following button creation code:
'Function for creating buttons
Public Sub CreateNewButton(font As String, x As Integer, y As Integer,
width As Integer, height As Integer,
name As String, text As String,
menu_type As Integer,
Optional hidden As Boolean = True,
Optional centered As Boolean = False)
'Create a button as an entity
Dim btn As Button = New Button
'Assign the location
If centered = True Then
btn.Location = New Point(x - width / 2, y - height / 2)
Else
btn.Location = New Point(x, y)
End If
'Assign other variables from function parameters
btn.Name = name
btn.Text = text
btn.Height = height
btn.Width = width
'Should the button be hidden when created?
If hidden = True Then
btn.Hide()
End If
'Change the font
If font = "Normal" Then
btn.Font = setFont(btn.Font, "Consolas", 18)
ElseIf font = "Small" Then
btn.Font = setFont(btn.Font, "Consolas", 12)
End If
'Assign the Handlers and non-function variables
btn.BackColor = Color.Gray
btn.Anchor = AnchorStyles.None
Me.Controls.Add(btn)
AddHandler btn.Click, AddressOf ButtonOnMouseClick
AddHandler btn.MouseHover, AddressOf ButtonOnMouseHover
AddHandler btn.MouseLeave, AddressOf ButtonOnMouseLeave
End Sub
So basically, it works like a charm when being used in this form. But when I've tried using it in a different form I realized that I had to create the same function again. This process would become tedious if I had to do it for each and every form.
That's why I decided to create a new module called Public Functions in which I would have common functions shared by each module. The problem is that once it's created it cannot be executed because it returns an error that 'Controls.add' was not previously declared.
I do believe that this is something really simple. I've tried looking for the libraries which could be missing and I've tried importing System.Windows.Forms.Controls but I still get the same error.
How do I actually create a Public Function which can be shared between different forms?
Thanks in advance, Alex
Sample code as requested:
Method 1 Passing the Controls collection to your helper function.
Public Sub CreateNewButton(parentControls As ControlCollection,
font As String, x As Integer, y As Integer,
width As Integer, height As Integer,
name As String, text As String,
menu_type As Integer,
Optional hidden As Boolean = True,
Optional centered As Boolean = False)
' Abbreviated implementation to illustrate the point
Dim newButton As New Button
newButton.Top = y
newButton.Left = x
newButton.Name = name
newButton.Text = text
parentControls.Add(newButton)
End Sub
Method 2 Passing the Parent container to your helper function.
Public Sub CreateNewButton(parent As Control,
font As String, x As Integer, y As Integer,
width As Integer, height As Integer,
name As String, text As String,
menu_type As Integer,
Optional hidden As Boolean = True,
Optional centered As Boolean = False)
' Abbreviated implementation to illustrate the point
Dim newButton As New Button
newButton.Top = y
newButton.Left = x
newButton.Name = name
newButton.Text = text
parent.Controls.Add(newButton)
End Sub
Screen shot of what it looks like.
* New 1 is from the first function
* New 2 is from the second function
These two functions can be called like this:
CreateNewButton(Me.Controls, "", 10, 10, 50, 20, "btnNew1", "New 1", 1)
CreateNewButton(Me, "", 100, 100, 50, 20, "btnNew2", "New 2", 1)
Create a class library(.DLL), say MyFunctionsLib.DLL which contains your functions and place it in the same folder of your new project folder (or in any sub folder).
When another new project is created, you add a reference to your 'DLL' file and you can access the functions.
In visual Studio 2017, File->New Project ->Visual Basic-> .NET Standard-> Class Library
and give a suitable name say MyFunctionsLib, click Ok
Eg.
Public NotInheritable Class MyFunctionsLib
Public Shared Function addTwoNums(a As Integer, b As Integer) As Integer
Return a+b
End Function
End Class
Build your project and use your 'DLL' with any other project.
I'm trying to use emgu.cv lib for contour function in vb.net. The problem is my var is not defined. This should come under lib emgu.cv which I have already imported.
Dim borderPen As New Pen(Color.FromArgb(150, 0, 255, 0))
Dim processor As ImageProcessor
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs)
Dim borderPen As New Pen(Color.FromArgb(150, 0, 255, 0))
If RadioButton1.Checked = True Then
For Each contour As var In processor.contours
If contour.Total > 1 Then
e.Graphics.DrawLines(Pens.Red, contour.ToArray())
End If
Next
End If
SyncLock processor.foundTemplates
For Each found As FoundTemplateDesc In processor.foundTemplates
If found.template.name.EndsWith(".png") OrElse found.template.name.EndsWith(".jpg") Then
DrawAugmentedReality(found, e.Graphics)
Continue For
End If
Next
End SyncLock
End Sub
Private Sub DrawAugmentedReality(found As FoundTemplateDesc, gr As Graphics)
Dim fileName As String = "C:\Users\pnasguna\Desktop\A56.jpg"
Dim AugmentedRealityImages As New Dictionary(Of String, Image)()
Dim img As Image = AugmentedRealityImages(fileName)
Dim p As Point = found.sample.contour.SourceBoundingRect.Center()
Dim state = gr.Save()
gr.TranslateTransform(p.X, p.Y)
gr.RotateTransform(CSng(180.0F * found.angle / Math.PI))
gr.ScaleTransform(CSng(found.scale), CSng(found.scale))
gr.DrawImage(img, New Point(-img.Width / 2, -img.Height / 2))
gr.Restore(state)
End Sub
I could not compile as var is not defined. How to fix this problem?
You get the Type <typename> is not defined error because the type var is not defined. You fix this by doing one of the following steps:
Remove As var.
For Each contour In processor.contours
Replace var with the correct data type.
For Each contour As <THE_CORRECT_TYPE> In processor.contours
Emgu
Looking at the source code for emgu (written in C#), the ImageProcessor.cs file will reveal the data type of contours:
public List<Contour<Point>> contours;
Translated into vb.net:
Public contours As List(Of Contour(Of Point))
Solution
So with this information it's pretty easy to pick the correct data type.
For Each contour As Contour(Of Point) In Me.processor.contours
Note: You should always have Option Strict set to On.
I am trying to write a function that returns a newly created object ( a form ) that is specified by the input. I'm having trouble with how to work out the concept of giving a type as an input then creating an object of that type in the body of the function. Here is an outline of what I'm working on.
Public Function MakeMyForm(ByVal frmType as Form) as Form
Dim NewObj as New frmType
Return NewObj
End Function
I'd like to be able to call the function in this way:
Dim myform as CustomFormType
myform = MakeMyForm(CustomFormType)
Can my concept be accomplished in VB.net?
Ok, if I understand you, you just want a generic method:
Public Function MakeMyForm(Of T As {New, Form})() As T
Return New T()
End Function
and call it like this:
Dim myform As CustomFormType = MakeMyForm(Of CustomFormType)()
of course, why wouldn't you just use:
Dim myform As New CustomFormType()
Well you can try this:
Dim frmnew() As Form
Dim createdforms As Integer = 0
Private Sub createform(wintext As String, height As Integer, width As Integer, backcolor As Color, topmost As Boolean, formborderstyle As FormBorderStyle, winstate As FormWindowState, opacity As Decimal, startposition As FormStartPosition, enabled As Boolean) 'add as many properties as you like
ReDim Preserve frmnew(createdforms)
frmnew(createdforms) = New Form
With frmnew(createdforms)
.Text = wintext
.Height = height
.Width = width
.BackColor = backcolor
.TopMost = topmost
.FormBorderStyle = formborderstyle
.WindowState = winstate
.Opacity = opacity
.StartPosition = startposition
.Enabled = enabled
End With
frmnew(createdforms).Show()
createdforms += 1
End Sub
and you can test it with the code below:
createform("Afnan Makhdoom", 500, 700, Color.Aqua, False, Windows.Forms.FormBorderStyle.Fixed3D, FormWindowState.Normal, 0.9, FormStartPosition.CenterScreen, True)
Public Function Makemyform(ByVal frmType As Form) As Form
Dim obj As Form
obj = newfunc(frmType)
Return obj
End Function
Public Function newfunc(ByVal mytype As Form) As Form
Return New Form
End Function
This is usually done using generics in a function such as:
Public Function GetItem(Of T)(key As String) As T
Usage:
myIntVar = myFoo.GetItem(Of Int32)(bar)
The purpose of which is for the code calling it to specify how it needs the return. In the above a whole bunch of data has been serialized and the original Type lost, so when fetching it back, the Of T helps convert it rather than using Object as the return.
For forms, it is more problematic:
Public Function MakeAForm(Of T)() As Form ' cant do As T
You'd have to add more code to cast Form to Form1 or frmCust to avoid tbName is not a member of System.Windows.Forms.Form errors. Even the correct way as shown by Mr Dokjnas present problems trying to do more with the form:
Public Function MakeAForm(Of T As {New, Form})() As T
Dim frm As New T
If frm.GetType Is frm8088.GetType Then
frm.textbox1.text = "ziggy" ' error
End If
Return frm
Here, it is 'TextBox is not a member of T`. If your forms were compiled to a ClassLib so the IDE could know more about the Types (forms) you could get it to work. But the first sign of futility is revealed in using it:
Dim frm As Form = MakeAForm(Of frm8100VI)()
frm.Show()
It takes more code to call the FormMaker than to just create an instance.
I'm trying to use lambdas in some VB.Net code, essentially I'm trying to set a flag when databound is called.
Simplified it looks like this:
Dim dropdownlist As New DropDownList()
dropdownlist.DataSource = New String() {"one", "two"}
Dim databoundCalled As Boolean = False
AddHandler dropdownlist.DataBound, Function(o, e) (databoundCalled = True)
dropdownlist.DataBind()
My understanding is that the databoundCalled variable should be set to true, clearly I'm missing something as the variable always remains false.
What do I need to do to fix it?
After looking over your code and scratching my head, I found a solution that works. Now, why this works over what you have, I am not clear. Maybe this will at least help you in the right direction. The key difference is I have a method that sets the value to true/false. Everything else is the same.
Here is my entire web project code:
Partial Public Class _Default
Inherits System.Web.UI.Page
Dim databoundCalled As Boolean = False
Dim dropdownlist As New DropDownList()
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Response.Write(databoundCalled)
Bind()
Response.Write(databoundCalled)
End Sub
Sub Bind()
AddHandler dropdownlist.DataBound, Function(o, e) (SetValue(True))
dropdownlist.DataSource = New String() {"one", "two"}
dropdownlist.DataBind()
End Sub
Function SetValue(ByVal value As Boolean) As Boolean
databoundCalled = value
Return value
End Function
End Class
I hope this helps!
Single line Lambdas in vb.net ALWAYS are expressions , what your lambda expression is doing is basically saying does databoundCalled = True or (databoundCalled == True) if your a c# guy , not set databoundCalled = True
The problem is how lambdas are interpreted. In VS2008 a Function lambda is always interpreted as an expression and not a statement. Take the following block of code as an example
Dim x = 42
Dim del = Function() x = 32
del()
In this case, the code inside the lambda del is not doing an assignment. It is instead doing a comparison between the variable x and the value 32. The reason why is that VB has no concept of an expression that is an assignment, only a statement can be an assignment in VB.
In order to do an assignment in a lambda expression you must have statement capabilities. This won't be available until VS2010 but when it is you can do the following
Dim del = Function()
x = 32
End Function
Essentially anything that is not a single line lambda is interpreted as a statement.