I want to stop people sending us messages including the word "telegram".
I have a very old script in VB that uses sendmail. It has always worked fine. Now I am trying to add this:
Sub CheckTelegram()
'check for Telegram
If messagetext.Contains("telegram") Then
messagetext.BorderColor = Drawing.Color.Red
Else
But I receive an error:
Compiler Error Message: BC30456: 'Contains' is not a member of 'System.Web.UI.WebControls.TextBox'.
Can I not use .Contains() this way? I was expecting the border to go red if "telegram" was within the text box.
the TextBox class itself is not a text. You must access the Text property which is of type String:
If messagetext.Text.Contains("telegram") Then
' ^^^^
Because Contains is a method of the String class, not a method of the TextBox class.
Note that older VB versions (VB 6.0, VBA) had the concept of default properties. You could effectively call s = Me!TextBox1 and if s was typed as String, VB was smart enough to see that a TextBox could not be assigned to s and the Text or Value property was automatically retrieved.
VB.NET has a stronger typing and also wants you to do more things explicitly (especially if you have Option Strict On, what I urge you to do). This is better for the understanding of the code and leads to less programing errors. E.g., if you have a declaration Dim obj As Object then what should obj = Me!TextBox1 do? Assign the TextBox or TextBox.Text? Such an automatism can be very confusing.
So I am trying to remove an item in a dictionary with a dictionary key via a property in a userform. So far, I have succeed to add a new item in dictionary, count item in the dictionary and get an item with userform property. So all of this is functional but I can't get the remove (key) functional.
Here is the property in my userform. (maybe I should use a get property?):
Public Property Let Materialremove(ByVal PartNumber As String)
DicMaterial.Remove (PartNumber)
End Property
Here is how I call for my property:
If UBidStatus.Materialexists(PartNumber) Then
UBidStatus.Materialremove (PartNumber)
End If
I get a Compile error:
Invalid use of property in VBA
I agree with Doug Glancy, I think you should turn it into a function. I don't think your approach is a good one. The reason you are having problems is because you are trying to treat a property like a function. You can make the code work this way: UBidStatus.Materialremove = PartNumber but I strongly advise against that for the sake of the next developer who has to look at the code after you and figure out what it's saying because what you are trying to do makes no logical sense. You should turn the property into a function. You need the assignment operator to make the line work because that is the purpose of a Let property statement: to assign a value to a property. But since you are trying to force a property to act like a function, it doesn't make any sense when someone tries to read the code.
I have a class module in an Excel project that has a property called Marks, this is a VB Collection and has a public get property (but no set or let).
I can assign values to this without any problem:
myObject.Marks.Add 3.14159
However, when I try to do something with this object (e.g., iterating through it), I get an error:
3021: Either BOF or EOF is true or the current record has been deleted
However, if I try myObject.Marks.Count, it shows that the collection contains the amount of data that I was expecting... I just can't access it!
I don't really understand why. I am using the same process with other collection properties within the object -- even collections of collections -- and they're working fine.
Any ideas?
myObject.myCollection.Add recordset!field adds the recordset field object to the myCollection object, rather than its value. As such, simply casting the field to its appropriate type solves the problem.
I'm trying to track down the cause of an annoying interface bug in an app that was recently upgraded from VS2003 to VS2008 (the bug did not exist pre-migration).
What happens is this :
1) User clicks in textbox containing a date.
2) User clears date
3) User tries to move to another field, but can't. No error messages appear - it's as if the validation failed.
Further info :
1) The textbox's Text property is bound to a dataview which uses a datatable as its source. The bound field is a nullable datetime field with no constraints or default.
2) The Validating event fires and the CancelEventArgs property is not set to Cancel. The Validated, LostFocus and Leave events all fire as well, going LostFocus > Leave > Validating
3) I can't see any code changes relating to the control or the datasource with a couple of exceptions. The first is that this :
Me.txtRangeEnd.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.dvClientNos, "RangeEnd"))
has now changed to this :
Me.txtRangeEnd.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.dvClientNos, "RangeEnd", True))
The second is that this :
Me.dcolRangeEnd.DataType = GetType(System.DateTime)
has now changed to this :
Me.dcolRangeEnd.DataType = GetType(Date)
There is also this, which has been in the code since day one :
AddHandler txtRangeEnd.DataBindings("Text").Format, AddressOf FormatBoxToDate
Private Sub FormatBoxToDate(ByVal sender As Object, ByVal e As ConvertEventArgs)
Try
If Not e.Value Is DBNull.Value Then
e.Value = Format(e.Value, "d")
End If
End Try
End Sub
Now, if I remove the ", True" from the adding of the databinding then I can exit the control with a blank value, but it then reverts to the original value. Removing the date formatting appears to make no difference to this (it just reverts to showing 06/01/2011 00:00:00 rather than the desired 06/01/2010). No other code refers to that textbox at all. I'm thinking something must have changed in validation of databound controls between VS2003 and VS2008, but it's just as likely I'm missing something mind-numbingly obvious.
Any ideas?
The reason that you're seeing the observed behaviour is to do with how Windows Forms and it's Data Binding handles NULL database values.
The TL;DR reason:
See this Microsoft Connect suggestion: Provide better databinding support for nullable types
The long version:
What is essentially happening is that as you clear the Textbox (to an empty string) and subsequently tab away, the binding is converting your empty string to a DBNull value which is then propagated to the data source however the binding, since it is two-way, then attempts to re-populate the bound control (the Textbox) with appropriate formatting, and fails, causing the Textbox to display the strange behaviour of not allowing the focus to be removed from it!
This is happening due to the DataSourceNullValue property of the Binding class. This can be set using one of the Binding classes constructor overloads, or set separately via a property setting, however, if you do not explicitly set this property, it is important to note that:
The default is DBNull for value types
and null for non-value types.
It appears that you're not explicitly setting this, so the default is applying, and with your DateTime being a value type, it is using DBNull.
Once the data source has been updated (to DBNull), the binding mechanism will attempt to then repopulate the Textbox with the newly updated data source value. When the underlying data source value is DBNull, the value used for the bound control is governed by the Binding class's NullValue property. Again, if this property is not explicitly set either via the relevant overloaded constructor argument or via the property setting itself, the default value will apply, which is:
The Object to be set as the control
property when the data source contains
a DBNull value. The default is null.
Of course, a Textbox's Text property can only be set to an object of type System.String and not a null value (Nothing in VB), so the TextBox fails to bind the representative value (null/nothing) of the data source's value (DBNull) to the bound control.
The way to correct this behaviour is to ensure that the Binding class's NullValue property is explicitly set to a suitable value. In this case, a zero-length string will suffice to correct the problem.
One way to achieve this is to change the line:
Me.txtRangeEnd.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.dvClientNos, "RangeEnd", True))
to:
Me.txtRangeEnd.DataBindings.Add(New System.Windows.Forms.Binding("Text", Me.dvClientNos, "RangeEnd", True, DataSourceUpdateMode.OnValidation, ""))
The key here is the very last parameter, which is the NullValue, set to a zero-length string (The DataSourceUpdateMode is also explicitly specified due to the arguments of the constructor, but it's being set to it's default value anyway).
Despite all of this, it does appear to be somewhat "odd" behaviour, if not an actual bug. This is also evidenced by others who appear to be experiencing the same issue (which is still prevalent in Visual Studio 2010/.NET 4.0!). This thread on the social.msdn.microsoft.com forums contains someone experiencing the same issue with some interesting possible explanations as to why this happens, and why Microsoft designed it this way.
There is also a Microsoft Connect suggestion that was reported back in 2005 that highlights the issue. This suggestion has been "Closed as Postponed". It appears that Microsoft do not consider it a bug, as a very reasonable workaround exists (the explicit setting of the Binding's NullValue property) which, arguably, should be done anyway for readability's sake. They will apparently consider the suggestion in the future.
Going back to why this didn't exist pre-.NET 2.0 (Visual Studio 2005) seems to be due to the fact that the entire data binding mechanism was completely revamped for the release of .NET Framework 2.0. Your original solution, being a VS2003 project was using .NET Framework 1.1 which did not have as rich a data binding feature-set. Although I no longer have a copy of VS2003 to hand to test this, I'm assuming the binding mechanism in .NET 1.1 made much more use of implicit conversions between the control's value and the data source's value. This appears to be supported when you examine the Binding class from .NET 1.1, compared with .NET 2.0 (or higher). For example, there was no way to (easily) control the actual two-way binding itself (and how values are converted between the form and the data source) or the formatting of said values.
I have had this type of error before and I had to ensure that the underlying data source (in my case it was a dataset) was not set to read only and that the column allowed `null' values.
Once I had done this everything worked fine. It seemed like that the error that was being thrown in the Data Bindings was swallowed up somewhere and didn't propagate up.
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.