Convert String back to Tab Control Property - vb.net

Background
I have serialized a tab control's property, selected tab. I Am using two objectlists to store the object preset object that is being serialized.
Dim _allPresetsList As New List(Of PresetObject)
Dim _XmlPresetsList As New List(Of PresetObject)
preset.TabPageProperty = TabControl1.SelectedTab.ToString()
Dim objStreamWriter As New StreamWriter(_XmlLocation)
Dim xml As New XmlSerializer(_allPresetsList.GetType)
xml.Serialize(objStreamWriter, _allPresetsList)
objStreamWriter.Close()
Code used to de-serialize
Dim objStreamReader As New StreamReader(_XmlLocation)
_XmlPresetsList = xml.Deserialize(objStreamReader)
objStreamReader.Close()
However I cannot convert it back, this is how I have done it successfully with other controls.
CheckBox1.Checked = _XmlPresetsList(0).CheckBox1Property.ToString()
This does not work though
TabControl1.SelectedTab = _XmlPresetsList(0).TabPageProperty.ToString()
I am getting this error
Value of type 'String' cannot be converted to
'System.Windows.Forms.TabPage'.
Question
How can I convert the tab control string property from string back?

This is what is probably causing your error:
preset.TabPageProperty = TabControl1.SelectedTab.ToString()
This is just going to save something like "TabPage: {TabPage1}". Since SelectedTab is an object property, it cant be serialized and saving the type name of it wont be much help in determining which was selected. As the error states you cant make a TabPage object from a string. Instead save and restore something simpler like the selected index:
preset.TabPageIndex = TabControl1.SelectedIndex
I am not sure of the internals of the PresetObject, but I would use typed properties - in this case Int32 rather than string. The serializer will convert back and forth for you.
You should also turn on Option Strict.
CheckBox1.Checked = _XmlPresetsList(0).CheckBox1Property.ToString()
Checked is a boolean, yet you are assigning a string value to it. Option Strict on will warn you when you are leaving VB to make this type of conversion.

Related

Convert Control Using Cast Not Working

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

Vb.net how can I set Search level as user input string

Intro... I've got a counter in my project that counts files in specified paths. Now all this depends on the users input as concerned would go into settings and set which extensions (tbExt1.text) that should be searched for as well as path (tbpath.text). The paths are listed in lbchannel1 listbox. Now this wont matter too much to my question, but I filled it in so my example below is more understandable.
Here comes the question: The users should be able to address if its going to count TopLevelOnly (FileIO.SearchOption.SearchTopLevelOnly) or TopAndSub (FileIO.SearchOption.SearchAllSubDirectories).
So I made a combobox that they can select from either of those two options. When they select one of them, FileIO.SearchOption.SearchTopLevelOnly or FileIO.SearchOption.SearchAllSubDirectories will become the text in a textbox tbTopOrSub1.text
That brings me to the next part. Instead of for example FileIO.SearchOption.SearchAllSubDirectories in my counter, I now added tbTopOrSub1.text as I hoped this would work the same way, but now be a user depended option. Have a look:
Dim TopOrSub1 As String
TopOrSub1 = tbTopOrSub1.Text
Dim fileTotal As Integer
For Each item As String In lbChannel1.Items
fileTotal += My.Computer.FileSystem.GetFiles(item.ToString, TopOrSub1, (tbExt1.Text)).Count
Next
I thought this would work like a charm, but it doesn't seem to work. I get this error The converting from string FileIO.SearchOption.SearchTopLev to type Integer is not valid (could be bad translation since the error was in Norwegian) and I notice how it sais TopLev. I suppose its too long? I can't figure out how to get around this.
First of all put Option Strict On for your VB project. This helps alot to avoid runtime errors.
The error occurs since you try to convert a string into an enumeration (=integer).
The good thing about comboboxes is that they have a DataSource property which can hold a collection of objects of any type. Additionally they have the following Properties:
DisplayMember: Name of a (public) property of the object set
in DataSource. The value of it will be displayed in the UI as "friendly" text.
ValueMember: Name of a property of the object set in DataSource. This value will not be shown in UI but you can accesss it in your code.
See my below exmaple how to use all these:
The object which holds the display text (Name) and the Value for your File Search Option:
Class FileSearchOption
Public Property Name As String
Public Property Value As FileIO.SearchOption
End Class
Fill your combobox and set its DataSource, DisplayMember and ValueMember:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim searchOptions As New List(Of FileSearchOption)
searchOptions.Add(New FileSearchOption() With {.Name = "TopLevelOnly", .Value = FileIO.SearchOption.SearchTopLevelOnly})
searchOptions.Add(New FileSearchOption() With {.Name = "TopAndSub", .Value = FileIO.SearchOption.SearchAllSubDirectories})
ComboBox1.DataSource = searchOptions
ComboBox1.DisplayMember = "Name"
ComboBox1.ValueMember = "Value"
End Sub
Handle the action when the user has chosen a search option. Remark that it is necessary to DirectCast the SelectedValue since it is of type Object.
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
Dim fileTotal As Integer
For Each item As String In {"G:\"}
fileTotal += My.Computer.FileSystem.GetFiles(item.ToString, DirectCast(ComboBox1.SelectedValue, FileIO.SearchOption), (tbExt1.Text)).Count
Next
End Sub

expression is a value and therefore cannot be the target of an assignment ERROR

Dim cntrl As ComboBox = DirectCast(cboorlstCntrl, ComboBox)
Dim adors As New ADODB.Recordset
cntrl.Items.Add(adors.Fields(1))
cntrl.Items.Add(cntrl.SelectedIndex) = adors.Fields(0)
in the vb.net code above,Last line shows the error.Please solve it
The Add() method is a sub, it is no object and it doesn't return any object either. This means that it cannot be assigned to anything (which is one of the things the equal (=) operator does).
Add() takes only one parameter, which is what to add to the ComboBox's items. So if you want to add anything to a specific index you'd use the Insert() method instead:
cntrl.Items.Insert(cntrl.SelectedIndex, adors.Fields(0))
For more info, see: Insert Method (Int32, Object) - MSDN

Com type object problems to get properties

I have the following code in VB.net :
Dim objWorkspace As Object
Dim nrobjects As Integer
Dim dataretrieved As Integer
objWorkspace = GetObject("", "Workspace.Application")
objWorkspace.Documents.Open("d:\testimage.grf")
nrobjects = objWorkspace.Parent.ActiveDocument.ActiveWindow.Application.ActiveDocument.Page.ContainedObjects.Count
Dim info() As PropertyInfo
For Each Item In objWorkspace.Parent.ActiveDocument.ActiveWindow.Application.ActiveDocument.Page.ContainedObjects
testvar = Item
info = testvar.GetType().GetProperties()
Next
The little script is connected to a button on a form. When the button is pressed, a custom program is opened (Workspace) and a test image is loaded into it. This part works.
Then I try to get the number of objects on the loaded image. This also works, but when I try to get their properties, I get all the time nothing.
I tested in debug mode. When I try to access the in objWorkspace using the watch, I get the value "COM Type", and the content I can access only if I press the "Dynamic" field "Expanding will evaluate all members dynamically".
How can I access the fields dynamically within the code?

Ambiguous match found

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.