Searchable List of Different Datatypes - vb.net

I'm working on an application that displays different customized form controls to users depending on the data type of the value that needs to be displayed. So, for example, a Boolean value appears as a check box. However, there are some types that I do not want to display. As the form and controls are generated at run-time, I need to build some logic that prevents these unsupported types from appearing.
Here's what I've tried to accomplish this:
I have a List unsupportedTypes As List(Of Type) that I fill with the types I want to exclude:
unsupportedTypes.Add(GetType(System.Drawing.Color))
'more types removed for brevity
This complies, but throws a null reference exception at the above line, which I suppose makes sense since there isn't any thing to put into the list. However, trying to create a color
unsupportedTypes.Add(GetType(New System.Drawing.Color))
will not even compile.
How can I build a list (or other collection) of different data types that I can search?

This compiles and works at runtime, so i don't really understand your issue:
Dim unsupportedTypes As New List(Of Type) ' New prevents a null reference exception
unsupportedTypes.Add(GetType(Drawing.Color))
Since you have mentioned i have a list: unsupportedTypes As List(Of Type), is it possible that you have forgotten to initialize it?

Related

What is the most idiomatic way to load and save values from an MFC CPropertySheet?

I have a class derived from CPropertySheet and I am having trouble finding the "correct" way to load values on startup and save values when the user presses OK. I'm surprised that I can't find any useful example on the web but there it is.
Ultimately, I need to read values from an external data source and write them back but for now, I have a void LoadValues(void) method on my property sheet that just uses some literals to initialize the controls on the property pages. This works when I call LoadValues() from OnInitDialog(). But if I do:
CMyPropertySheet* pSheet = new CMyPropertySheet("My Title");
pSheet->LoadValues();
if (pSheet->DoModal() == IDOK) {
pSheet->SaveValues();
delete pSheet;
}
(as Microsoft suggests) the values are not there when the property page is displayed; the controls are empty or contain default values. All the MFC control value setting routines seem to return void so there's nothing to test for success. I did read back a value in LoadValues() after I set it and I get the correct value.
Also, SaveValues() sees gibberish. Perhaps the property sheet is torn down before I get out of DoModal() to the values aren't there any more?
I've been told that values should get loaded in OnInitDialog() and I guess I can get my external data source to the object in the constructor but that leaves me having no idea where to save values. There doesn't seem to be a CPropertySheet::OnOK() method. What am I missing?
Although you are working with a property sheet the same issues apply to all modal dialogs. Before you call DoModal the controls do not exist. So if your LoadValues call is attempting to access the controls it will not work. (This would normally produce an assertion in a debug build.) What you need is a two-step operation: (1) LoadValues can access data members of the sheet, so pass the values to the sheet's data members that you create for that purpose. (2) In OnInitDialog of the sheet you can initialize the controls from the data members.
SaveValues needs a similar two-step because the controls no longer exist after DoModal returns. (1) In the sheet's OnOK or equivalent move the data from controls to data members. (2) After DoModal returns you can access the data members to do the SaveValues.

Get Values from Listbox for if functions

Hey guys very new here.
Have a listbox that gets account names from a specific game server using this command line
Dim apikeyinfo As APIKeyInfo = api.getApiKeyInfo()
lstbxCharacters.DataSource = apikeyinfo.Characters
this code gets all the characters in a single account by displaying it in a listbox.
Now i would like to reference a character from the lisbox but not sure how
Any method such as Listbox.Get to get the value and compare it with something else?
Thanks
you can try something like
lstbxCharacters.SelectedItem
Update
To read the data from the listbox I think there are multiple ways (Assuming that it is readable).
-> Usually listbox display strings, so it should work to read to a string variable
Dim a_string as Strin = lstbxCharacters.SelectedItem
also you may like to add a small check before, assuring that an Item is currently selected:
If lstbxCharacters.SelectedIndex < 0 then return
This jumps out of current sub if no item is selected
And finally, to read the first entry, you can also do it this way:
a_string = lstbxCharacters.Items(0)
if it returns objects, then instead of accessing the object directly, it may work to do
a_string = lstbxCharacters.Items(0).ToString
(most objects allow a .ToString() Function )
Here two ideas for different solutions:
As a user commented, you could access the DataSource directly + the information which listIndex was selected. But if you do so, then maybe it is more easy (if you need to access it anyways, to go with solution 2)
Create a variable of type list(Of some_object) and fill it with the data from the datasource. It will take some time to do this, but if you define for the class some_object a function ToString, then you can fill all objects directly to the lstbxCharacters, and access them without any worries, by doing CType(lstbxCharacters.SelectedItem, some_object)
Update 2
If with reference you mean to access further information from the datasource, then you need to build some kind of query, or set the content of the listbox in relation to another control that shows the database content (in that way the listbox lstbxCharacters would act like a filter)

How would one detect a property of type "InvalidOperationException" within a collection?

Consider the following vb.net code for an office add-in (for access):
td = db.TableDefs(objectName)
For Each fld In td.Fields
For Each fldprp In fld.Properties
Debug.Print(fldprp.Value.ToString())
Next
Next
the variable "db" is a .net representation of the access vba return result from "Application.CurrentDB()". "td" is of type "DAO.TableDefClass".
This code throws an exception of type "InvalidOperationException" when the value of the fldprp.value property cannot be determined (in Visual Studio, it shows the value as {"Invalid Operation."} in the watch window). fldprp.name, however, is available.
There are only a few properties which this occurs on. I'd like to be able to loop through all the fld.properties and output the values, but ONLY if it is not an exception.
I am pretty sure why it is happening (certain properties are not available in this context). What I need to know is how to detect this at run-time so i can skip the property.
I can't seem to find a solution that will work. Help would be greatly appreciated.
Inside the body of the inner loop, put this at the top:
If TypeOf fldprp Is InvalidOperationException Then Continue
http://msdn.microsoft.com/en-us/library/0ec5kw18%28VS.80%29.aspx
I don't know your specific situation, but what I would suggest is using an explicit filter for the object types you want to include instead of filtering out the ones you don't want to include.

How to run a string as a command in Visual Basic (VB.NET)

i am running a Sub which takes as arguments a Datatable and a String.
Private Sub Populate(ByVal dttemp As DataTable, ByVal strWhichPart As String)
At one point there is a combobox which is populated with some of the data in the datatable. The name of the combobox is cmd plus the name of the string for example when the string is Person_FirstName the name of the combobox is cmbPerson_FirstName. Then i add items to the combobox like this:
cmbPerson_FirstName.Items.Add(strHold(rr))
My question is this can i make a String into a command? Because i have many comboboxes which have the same name as the string argument of the sub how can i do something like this to work
strWhichPart.Items.Add(strHold(rr))
in which strWhichPart is a string. Is there a command that i can execute a string as a command?
Thank you.
If I understand correctly, just grab the correct control from the Form's Controls collection using the string as the key:
CType(Controls(strWhichPart), ComboBox).Items.Add(strHold(rr))
You can use reflection to achieve this by creating an assembly with the code in a method, but its really not recommended. As in, it's insane. I suspect there are no problems in .NET development that need this approach.
Rather than using this approach, actually pass the relevant combo box as an argument - not an arbitrary string. Combo boxes are objects like anything else. You could create a dictionary which allows you to lookup combo boxes by a string. Something like:
Dictionary(Of String, ComboBox) MyDictionary = new Dictionary(Of String, ComboBox)()
MyDictionary.Add("ComboBoxA", objComboBoxA)
ComboBox objTheComboBox = MyDictionary("ComboBoxA")
The name you give your objects should not be semantically relevant in your code. If I name an object "lstMyObjectNamedThisWayForAReason1" I should NOT be using that to reference it. Instead, there should be a separation between what constitutes a GUI element and how it is referenced.
For example, if I create a WinForms GUI and reference all the items directly, then later have to write another front-end using a different framework I have to rewrite every reference. This isn't a problem if you don't tie your logic directly into your controls.
The only reason to tie them together is laziness and lack of respect for co-workers who might have to improve on your code in future. Why should they care what the GUI looks like? They might not even be using Visual Studio! They certainly can't take your code and use it elsewhere without ripping out your GUI dependency.
With a minor modification of ho1 it worked. Thanks a lot
CType(Controls("cmb" + strWhichPart), ComboBox).Items.Add(strHold(rr))

Casting problem after obfuscation with Dotfuscator

I'm trying to obfuscate some VB.NET 2003 app.
The resulting assemblyes are obfuscated and "run" with some errors.
I cleaned all potential reflection problems, but I'm not being able to read the selected value of a combobox.
I load the Combobox using their Datasource properties, using a collection of "VTPair" (a class created by me with 2 properties: one of string type and other of object type to store the value)
This combobox handle pairs like "Male | M" or "Female | F".
When trying to see what is selected, I use if mycombo1.SelectedValue = "M" then
This code, after obfuscation, throws me an exception that cannot cast type "XX" to string "M".
So, I changed the code to something more correct, explicitly casting the selected value to String:
if ctype(mycombo1.SelectedValue,string) = "M" then
But the error is the same.
Debugin my original code, the SelectedValue property is of type "Object" but it is a string.
I tried using the ComboBox.SelectedItem property that is also an object but this time what is inside is of type "VTPair" (my own class) and then trying to access its "Value" property (which is of type Object) and trying to cast to string fails again.
Does anyone have an idea to "translate" this piece of code to work OK after Dotfucate it?
Thanks!
From MSDN:
ListControl.SelectedValue Property:
Gets or sets the value of the member property specified by the ValueMember property.
So whatever property NAME you set for the ValueMember property will be used when you use the SelectedValue property. So you may need to exclude from obfuscation, the property which you specify via the ComboBox.ValueMember property.
Not sure of the VB Syntax but in C# I think you would want something where the right-hand side is typeof(MyType). This way the type will be obfuscated to match the renamed type.