i have a control named SuperValidator1 on every form with SuperValidator type. i want to find this control and enable it using its name because the name is consistent in all forms. so this is the code i came up with :
Dim validator As SuperValidator
Dim frm As Form = Me.ParentForm
Dim ctrl As Control()
ctrl = frm.Controls.Find("SuperValidator1", True)
Dim singleCtrl As Control = ctrl(0)
validator = TryCast(singleCtrl, SuperValidator) '< ERROR LINE
it throws editor error : Value of Type 'Control' cannot be converted to 'SuperValidator'
i tried CType and DirectCast but it is the same. according to this i should be able to cast any data type. what is wrong and what should i do ?
btw SuperValidator is from DevComponents.DotNetBar.Validator
thanks
Since SuperValidator is a component you must get it from your form's component collection. However at runtime components don't seem to inherit a name, so finding the exact one might be tricky.
As far as I know your only options are:
A) Get the first SuperValidator you can find, or
B) Match its properties (if possible).
Either way you do it you must iterate through the Me.components.Components collection:
Dim validator As SuperValidator = Nothing
For Each component In Me.components.Components
If component.GetType() Is GetType(SuperValidator) Then
validator = DirectCast(component, SuperValidator)
'Perform additional property checking here if you go with Option B.
End If
Next
Here is a test that uses a control I have on a form. Changed your logic slightly. Give it s try and see what results you have.
Dim validator As RichTextBox ' SuperValidator
Dim frm As Form = Me ' .ParentForm
Dim ctrl() As Control = frm.Controls.Find("RichTextBox1", True) ' ("SuperValidator1", True)
If ctrl.Length > 0 Then
validator = TryCast(ctrl(0), RichTextBox) ' , SuperValidator) < ERROR LINE
Else
Stop
End If
Related
I want to create a function that receives forms as an input. I need to use controls' properties of the passed form. For example:
Private Sub Drawing(ByVal frm As Form)
X = frm.a.Left + frm.a.Width
End Sub
Visual basic doesn't accept this method that I use. How can I solve it?
The code should be like this :
Private Sub Drawing(ByVal frm As Form)
Dim i As Control()
i = frm.Controls.Find("a", True)
if i.Length <> 0 Then
X = i(0).Left + i(0).Right
End If
End Sub
"Visual Basic doesn't accept this method that I use" is a very vague description of your problem. You should be specific with what errors you get and what you want the result to be, because we are not mindreaders and can therefore not tell what the problem is unless we get clear information.
But if you're trying to change a control's/form's X-position you have to change the entire Location property.
Change the current form's X-position:
Me.Location = New Point(frm.a.Left + frm.a.Width, Me.Location.Y)
Change a control's X-position (where YourControl is the name of the control you want to move):
YourControl.Location = New Point(frm.a.Left + frm.a.Width, YourControl.Location.Y)
I'm trying to assign text from "comp" in the form "home" to a textbox with the name "d1" in the form "home".
but this needs to be done with a counter in the form "home".
The code is in a module.
What I've tried=
home.controls("d" & home.counter).text = home.comp.text
I keep getting an error:
use the new keyword to create an object instance ==> the textbox exists in the form
check to determine if the object is null before calling the method ==> the textbox is empty
get general help for this exception
You could use Controls.Find:
Dim controls = home.Controls.Find("d" & home.counter, True)
If controls.Length > 0 Then
Dim txt = TryCast(controls(0), TextBoxBase)
If txt IsNot Nothing Then
txt.Text = home.comp.text
End If
End If
However, normally i would not use this approach since it's error-prone. Why don't you provide a public property in the Home-form that you can access? This property would get/set the TextBox' Text.
For example:
Public Property HomeCompText As String
Get
Return txtHomeComp.Text
End Get
Set(value As String)
txtHomeComp.Text = value
End Set
End Property
Now you can use this clear, safe and maintainable code:
home.HomeCompText = home.comp.text
You could even change the underlying control.
Please, can anyone help me with this problem:
I have a name(s) of control(s) in string format (str) and I want to set property (in code) of that controls using that string-name.
I try something like this but it doesn't work. Actually, I have a problem with expression. When I put exactly the name it works but when i use variable in string format it doesn't.
Dim str as String
str="k3"
Dim g As Image = CType(str, Image)
g.Source = New BitmapImage(New Uri("/APP;component/Icons/hero.png", UriKind.Relative))
This works:
Dim g As Image = CType(k3, Image)
While this does not:
Dim g As Image = CType(str, Image)
I think I understand what you are trying to do, to declare an object by a string...
Essentially for this to work you will need a custom function that returns the Object Type that you are seeking...
You will need to loop through each control and check the name of the control as a comparison, e.g. If oControl.Name.ToString = sString then Return oControl
Example
' A function to return a Control by the Control's name...
Public Function GetControlByName(ByVal oForm As Form, ByVal sName As String) As Control
Dim cReturn As New Control
Dim ctrl As Control
For Each ctrl In oForm.Controls
cReturn = ctrl
If ctrl.Name.ToString = sName Then
Return ctrl ' this is what we want!
End If
Next
Return cReturn
End Function
' Example Usage
Dim oButton As Button = GetControlByName(Me, "Button44")
If oButton.Name.ToString = "Button44" Then
MessageBox.Show("I have found your Button!")
Else
MessageBox.Show("Your button was NOT Found!")
End If
Obviously there is room for error with this function, because if sName is NOT found, then it will return the last ctrl found, therefore, you will need to ensure that the control you seek is indeed found, via the If statement as provided in the example above...
Furthermore, it may not loop through controls inside of containers, menus, etc, but I'm not sure on that, so you will need to check to ensure it's not having that problem...
(The Me in the statement will most likely be used more often than not, though Me could be the name of the form you are searching if you are running the code outside of the form you are searching the form with the function.)
FINALLY, to answer your question, you will need to change Control to Image, and Set CReturn as a New Image, and then use Return ctrl.BackgroundImage (etc) to return the image..
I face a problem with Ambiguous match found
What I am trying to do is described in :GetType.GetProperties
In two words I am trying to run through all the properties of a control and find if user had made any changes to control's properties , then I take only the changed properties and store the values for these properties
I followed the suggestions but I get an error for propery Padding when the control is a TabControl (the tabControl has 2 tabPages).
Ok with help from Ravindra Bagale I manage to solve it:
The problem wasn't the new modifier but my stupidity:
In MSDN is says:
Situations in which AmbiguousMatchException occurs include the following:
A type contains two indexed properties that have the same name but different numbers of parameters. To resolve the ambiguity, use an overload of the GetProperty method that specifies parameter types.
A derived type declares a property that hides an inherited property with the same name, by using the new modifier (Shadows in Visual Basic). To resolve the ambiguity, use the GetProperty(String, BindingFlags) method overload and include BindingFlags.DeclaredOnly to restrict the search to members that are not inherited.
So I used BindingFlags.DeclaredOnly and the problem solved:
Private Sub WriteProperties(ByVal cntrl As Control)
Try
Dim oType As Type = cntrl.GetType
'Create a new control the same type as cntrl to use it as the default control
Dim newCnt As New Control
newCnt = Activator.CreateInstance(oType)
For Each prop As PropertyInfo In newCnt.GetType().GetProperties(BindingFlags.DeclaredOnly)
Dim val = cntrl.GetType().GetProperty(prop.Name).GetValue(cntrl, Nothing)
Dim defVal = newCnt.GetType().GetProperty(prop.Name).GetValue(newCnt, Nothing)
If val.Equals(defVal) = False Then
'So if something is different....
End If
Next
Catch ex As Exception
MsgBox("WriteProperties : " & ex.Message)
End Try
End Sub
I have to apologize.
My previous answer was wrong.
With BindingFlags.DeclaredOnly I don't get the properties that I wanted.
So I had to correct the problem with other way.
The problem occurs because two properties have the same name.
So I searched where the same named properties are different and I found that they have: have different declaringType,MetadataToken and PropertyType.
So I change the way I get the value and problem solved:
Dim val = cntrl.GetType().GetProperty(prop.Name, prop.PropertyType).GetValue(cntrl, Nothing)
Dim defVal = newCnt.GetType().GetProperty(prop.Name,prop.PropertyType).GetValue(newCnt,Nothing)
Sorry if I misguided someone.
Can someone help me fix this error?
Option Strict On disallows late binding
Here's the code that's causing the error:
Dim SF6StdData As BindingSource = New BindingSource()
' ...
If StrComp(SF6StdData.Current("O2AreaCts").ToString, "") = 0 Then
AreaCts(3) = 0
Else
AreaCts(3) = Convert.ToDouble(SF6StdData.Current("O2AreaCts").ToString)
End If
I need to rewrite the code so it will not have any errors. I know I could fix this by setting Option Strict to Off in the project properties, but I really don't want to do that. Is there some other way?
Late binding is not allowed when Option Strict is on. If you need to perform late binding, the only options are either to use reflection or to shut off Option Strict. The one saving grace, however, is that you don't have to shut off Option Strict for the whole project. You can leave it on for the project and then just add the line Option Strict Off at the top of any code files where you need to perform late binding. It's not a great solution, but it's better than affecting the whole project.
Also, since the Option Strict placed at the top of a file applies just to that file, it doesn't even have to apply to an entire class. If you split your class into multiple Partial Class files, then you could have Option Strict set differently for each of those files. For instance, if you put most of your class in a file with Options Strict On, and then just put one method in a Partial Class in a separate file with Option Strict Off, then only that one method would be compiled loosely. The rest of the class would be compiled using the strict rules.
You need to make the BindingSource act as a strongly-typed data source. See the remarks in the documentation: http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.aspx
This is an old post, but I struggled with the error "Option Strict On disallows late binding". Maybe another answer will help someone else. The problem may be coming when you try to convert the data in your SF6StdData bindingsource to a string. You can probably solve the problem by defining a local variable with the desired type, and then using Ctype to extract the data into the correct type. Here's an example of how I solved a similar problem.
This code gave me the late-binding error:
Friend Function CountNumCheckedInGroupbox(ByVal gbox As GroupBox, ByRef nameschecked() As String) As Integer
Dim numchecked As Integer = 0
For Each ctrl In gbox.Controls
If TypeOf ctrl Is CheckBox Then
If ctrl.Checked = True Then
nameschecked(numchecked) = ctrl.Text
numchecked += 1
End If
End If
Next
Return numchecked
End Function
The late binding error occurred where I referenced "ctrl.Checked" and "ctrl.Text"
Instead of referencing "ctrl" directly, I defined a variable cbox that is typed as a Checkbox. Then I extracted the information from "ctrl" into cbox. Now the code does not show late-binding errors:
Friend Function CountNumCheckedInGroupbox(ByVal gbox As GroupBox, ByRef nameschecked() As String) As Integer
Dim numchecked As Integer = 0
Dim cbox As CheckBox
For Each ctrl In gbox.Controls
If TypeOf ctrl Is CheckBox Then
cbox = CType(ctrl, CheckBox)
If cbox.Checked = True Then
nameschecked(numchecked) = cbox.Text
numchecked += 1
End If
End If
Next
Return numchecked
End Function
If you declared AreaCts without a type, ex:
Dim AreaCts as Array
Try
Dim AreaCts() as Double
This fixed my late binding error.