I took some code from a C# project and put it into a converter. The original code was:
(Nullable<bool>)false
and the converter said the VB equivalent is:
DirectCast(False, Nullable(Of Boolean))
I even compiled the C# project and looked at it in Reflector. It gave the same VB code as above, but this generates the error:
Value of type 'Boolean' cannot be converted to 'Boolean?'
How do I cast this properly?
More Code as requested:
Imports System.Windows
Imports System.Windows.Controls.Primitives
Imports System.Windows.Input
Public Class VirtualToggleButton
Public Shared ReadOnly IsCheckedProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsChecked", _
GetType(Nullable(Of Boolean)), _
GetType(VirtualToggleButton), _
New FrameworkPropertyMetadata(DirectCast(False, Nullable(Of Boolean)), _
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault Or _
FrameworkPropertyMetadataOptions.Journal, _
New PropertyChangedCallback(AddressOf OnIsCheckedChanged)))
Public Shared Function GetIsChecked(ByVal d As DependencyObject) As Nullable(Of Boolean)
Return DirectCast(d.GetValue(IsCheckedProperty), Nullable(Of Boolean))
End Function
Public Shared Sub SetIsChecked(ByVal d As DependencyObject, ByVal value As Nullable(Of Boolean))
d.SetValue(IsCheckedProperty, value)
End Sub
Private Shared Sub OnIsCheckedChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
Dim pseudobutton As UIElement = TryCast(d, UIElement)
If pseudobutton IsNot Nothing Then
Dim newValue As Nullable(Of Boolean) = DirectCast(e.NewValue, Nullable(Of Boolean))
If newValue = True Then
RaiseCheckedEvent(pseudobutton)
ElseIf newValue = False Then
RaiseUncheckedEvent(pseudobutton)
Else
RaiseIndeterminateEvent(pseudobutton)
End If
End If
End Sub
Public Shared ReadOnly IsThreeStateProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsThreeState", _
GetType(Boolean), _
GetType(VirtualToggleButton), _
New FrameworkPropertyMetadata(CBool(False)))
Public Shared Function GetIsThreeState(ByVal d As DependencyObject) As Boolean
Return CBool(d.GetValue(IsThreeStateProperty))
End Function
Public Shared Sub SetIsThreeState(ByVal d As DependencyObject, ByVal value As Boolean)
d.SetValue(IsThreeStateProperty, value)
End Sub
Public Shared ReadOnly IsVirtualToggleButtonProperty As DependencyProperty = DependencyProperty.RegisterAttached("IsVirtualToggleButton", _
GetType(Boolean), _
GetType(VirtualToggleButton), _
New FrameworkPropertyMetadata(CBool(False), _
New PropertyChangedCallback(AddressOf OnIsVirtualToggleButtonChanged)))
Public Shared Function GetIsVirtualToggleButton(ByVal d As DependencyObject) As Boolean
Return CBool(d.GetValue(IsVirtualToggleButtonProperty))
End Function
Public Shared Sub SetIsVirtualToggleButton(ByVal d As DependencyObject, ByVal value As Boolean)
d.SetValue(IsVirtualToggleButtonProperty, value)
End Sub
Private Shared Sub OnIsVirtualToggleButtonChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
Dim element As IInputElement = TryCast(d, IInputElement)
If element IsNot Nothing Then
If CBool(e.NewValue) Then
AddHandler element.MouseLeftButtonDown, New MouseButtonEventHandler(AddressOf VirtualToggleButton.OnMouseLeftButtonDown)
AddHandler element.KeyDown, New KeyEventHandler(AddressOf VirtualToggleButton.OnKeyDown)
Else
RemoveHandler element.MouseLeftButtonDown, New MouseButtonEventHandler(AddressOf VirtualToggleButton.OnMouseLeftButtonDown)
RemoveHandler element.KeyDown, New KeyEventHandler(AddressOf VirtualToggleButton.OnKeyDown)
End If
End If
End Sub
Friend Shared Function RaiseCheckedEvent(ByVal target As UIElement) As RoutedEventArgs
If target Is Nothing Then
Return Nothing
End If
Dim args As New RoutedEventArgs()
args.RoutedEvent = ToggleButton.CheckedEvent
[RaiseEvent](target, args)
Return args
End Function
Friend Shared Function RaiseUncheckedEvent(ByVal target As UIElement) As RoutedEventArgs
If target Is Nothing Then
Return Nothing
End If
Dim args As New RoutedEventArgs()
args.RoutedEvent = ToggleButton.UncheckedEvent
[RaiseEvent](target, args)
Return args
End Function
Friend Shared Function RaiseIndeterminateEvent(ByVal target As UIElement) As RoutedEventArgs
If target Is Nothing Then
Return Nothing
End If
Dim args As New RoutedEventArgs()
args.RoutedEvent = ToggleButton.IndeterminateEvent
[RaiseEvent](target, args)
Return args
End Function
Private Shared Sub OnMouseLeftButtonDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
e.Handled = True
UpdateIsChecked(TryCast(sender, DependencyObject))
End Sub
Private Shared Sub OnKeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
If e.OriginalSource Is sender Then
If e.Key = Key.Space Then
If (Keyboard.Modifiers And ModifierKeys.Alt) = ModifierKeys.Alt Then
Return
End If
UpdateIsChecked(TryCast(sender, DependencyObject))
e.Handled = True
ElseIf e.Key = Key.Enter AndAlso CBool(TryCast(sender, DependencyObject).GetValue(KeyboardNavigation.AcceptsReturnProperty)) Then
UpdateIsChecked(TryCast(sender, DependencyObject))
e.Handled = True
End If
End If
End Sub
Private Shared Sub UpdateIsChecked(ByVal d As DependencyObject)
Dim isChecked As Nullable(Of Boolean) = GetIsChecked(d)
If isChecked = True Then
SetIsChecked(d, If(GetIsThreeState(d), DirectCast(Nothing, Nullable(Of Boolean)), DirectCast(False, Nullable(Of Boolean))))
Else
SetIsChecked(d, isChecked.HasValue)
End If
End Sub
Private Shared Sub [RaiseEvent](ByVal target As DependencyObject, ByVal args As RoutedEventArgs)
If TypeOf target Is UIElement Then
TryCast(target, UIElement).[RaiseEvent](args)
ElseIf TypeOf target Is ContentElement Then
TryCast(target, ContentElement).[RaiseEvent](args)
End If
End Sub
End Class
It looks like you can just remove the DirectCast. From what I see you are passing a false into a function/method that has a Boolean? (or Nullable(of Boolean)) as a parameter. VB does not need the explicit casting that C# requires (although it's not a bad idea in some cases). For a simple example,
Private Function DoSomething(byval param as Boolean?) as Boolean?
'do something and return a Nullable(of Boolean)
End Function
DoSomething(false) 'is just fine, no DirectCast needed
DoSomething(nothing) 'is also fine
DoSomething(true) 'fine
DoSomething(DirectCast(false, Nullable(of Boolean)) 'will give you the error you described
Just as a side note, in case it is confusing Nullable(of Boolean) and Boolean? mean the same thing which is that it is a boolean variable that can have a value of true, false or nothing.
TKTS is correct that VB normally doesn't need the explicit cast, but, for completeness, the "correct" conversion would be:
New Boolean?(False)
Related
I have tried the autocomplete code from here :
Need a VB.net Combobox derived class for pattern matched or contains autocomplete functionality
I added some code and I really don't understand why the NbrName is lost.
I added :
Case Keys.Enter
Text = _suggLb.Text
[Select](0, Text.Length)
_suggLb.Visible = False
'Mika
Dim myObject As Form1 = New Form1()
myObject.SearchByName(Text)
'Mika
Return
and this :
Public Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
'Mika Dim testbox As New AutoCompleteComboBox.SuggestComboBox
Me.Controls.Add(testbox)
testbox.DataSource = New List(Of String) From {"Janean Mcgaha", "Tama Gaitan", "Jacque Tinnin", "Elvira Woolfolk", "Fransisca Owens", "Minnie Ardoin",
"Renay Bentler", "Joye Boyter", "Jaime Flannery", "Maryland Arai", "Walton Edelstein", "Nereida Storrs",
"Theron Zinn", "Katharyn Estrella", "Alline Dubin", "Edra Bhatti", "Willa Jeppson", "Chelsea Revel",
"Sonya Lowy", "Danelle Kapoor"}
NbrName = 20
End Sub
Public Sub SearchByName(text As String)
Dim StrTmp As String
StrTmp = text + NbrName.ToString
End Sub
and unfortunately, the variable NbrName remains to 0.
Here under the whole code.
Can someone explain me where is the problem ?
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Drawing
Imports System.Linq
Imports System.Linq.Expressions
Imports System.Windows.Forms
Public Class Form1
Dim testbox As New AutoCompleteComboBox.SuggestComboBox
Public NbrName As Integer
Public Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
'Mika Dim testbox As New AutoCompleteComboBox.SuggestComboBox
Me.Controls.Add(testbox)
testbox.DataSource = New List(Of String) From {"Janean Mcgaha", "Tama Gaitan", "Jacque Tinnin", "Elvira Woolfolk", "Fransisca Owens", "Minnie Ardoin",
"Renay Bentler", "Joye Boyter", "Jaime Flannery", "Maryland Arai", "Walton Edelstein", "Nereida Storrs",
"Theron Zinn", "Katharyn Estrella", "Alline Dubin", "Edra Bhatti", "Willa Jeppson", "Chelsea Revel",
"Sonya Lowy", "Danelle Kapoor"}
NbrName = 20
End Sub
Public Sub SearchByName(text As String)
Dim StrTmp As String
StrTmp = text + NbrName.ToString
End Sub
End Class
Namespace AutoCompleteComboBox
Public Class SuggestComboBox
Inherits ComboBox
#Region "fields and properties"
Private ReadOnly _suggLb As New ListBox() With {.Visible = False, .TabStop = False}
Private ReadOnly _suggBindingList As New BindingList(Of String)()
Private _propertySelector As Expression(Of Func(Of ObjectCollection, IEnumerable(Of String)))
Private _propertySelectorCompiled As Func(Of ObjectCollection, IEnumerable(Of String))
Private _filterRule As Expression(Of Func(Of String, String, Boolean))
Private _filterRuleCompiled As Func(Of String, Boolean)
Private _suggestListOrderRule As Expression(Of Func(Of String, String))
Private _suggestListOrderRuleCompiled As Func(Of String, String)
Public Property SuggestBoxHeight() As Integer
Get
Return _suggLb.Height
End Get
Set(value As Integer)
If value > 0 Then
_suggLb.Height = value
End If
End Set
End Property
''' <summary>
''' If the item-type of the ComboBox is not string,
''' you can set here which property should be used
''' </summary>
Public Property PropertySelector() As Expression(Of Func(Of ObjectCollection, IEnumerable(Of String)))
Get
Return _propertySelector
End Get
Set(value As Expression(Of Func(Of ObjectCollection, IEnumerable(Of String))))
If value Is Nothing Then
Return
End If
_propertySelector = value
_propertySelectorCompiled = value.Compile()
End Set
End Property
'''<summary>
''' Lambda-Expression to determine the suggested items
''' (as Expression here because simple lamda (func) is not serializable)
''' <para>default: case-insensitive contains search</para>
''' <para>1st string: list item</para>
''' <para>2nd string: typed text</para>
'''</summary>
Public Property FilterRule() As Expression(Of Func(Of String, String, Boolean))
Get
Return _filterRule
End Get
Set(value As Expression(Of Func(Of String, String, Boolean)))
If value Is Nothing Then
Return
End If
_filterRule = value
_filterRuleCompiled = Function(item) value.Compile()(item, Text)
End Set
End Property
'''<summary>
''' Lambda-Expression to order the suggested items
''' (as Expression here because simple lamda (func) is not serializable)
''' <para>default: alphabetic ordering</para>
'''</summary>
Public Property SuggestListOrderRule() As Expression(Of Func(Of String, String))
Get
Return _suggestListOrderRule
End Get
Set(value As Expression(Of Func(Of String, String)))
If value Is Nothing Then
Return
End If
_suggestListOrderRule = value
_suggestListOrderRuleCompiled = value.Compile()
End Set
End Property
#End Region
''' <summary>
''' ctor
''' </summary>
Public Sub New()
' set the standard rules:
_filterRuleCompiled = Function(s) s.ToLower().Contains(Text.Trim().ToLower())
_suggestListOrderRuleCompiled = Function(s) s
_propertySelectorCompiled = Function(collection) collection.Cast(Of String)()
_suggLb.DataSource = _suggBindingList
AddHandler _suggLb.Click, AddressOf SuggLbOnClick
AddHandler ParentChanged, AddressOf OnParentChanged
End Sub
''' <summary>
''' the magic happens here ;-)
''' </summary>
''' <param name="e"></param>
Protected Overrides Sub OnTextChanged(e As EventArgs)
MyBase.OnTextChanged(e)
If Not Focused Then
Return
End If
_suggBindingList.Clear()
_suggBindingList.RaiseListChangedEvents = False
_propertySelectorCompiled(Items).Where(_filterRuleCompiled).OrderBy(_suggestListOrderRuleCompiled).ToList().ForEach(AddressOf _suggBindingList.Add)
_suggBindingList.RaiseListChangedEvents = True
_suggBindingList.ResetBindings()
_suggLb.Visible = _suggBindingList.Any()
If _suggBindingList.Count = 1 AndAlso _suggBindingList.[Single]().Length = Text.Trim().Length Then
Text = _suggBindingList.[Single]()
[Select](0, Text.Length)
_suggLb.Visible = False
End If
End Sub
#Region "size and position of suggest box"
''' <summary>
''' suggest-ListBox is added to parent control
''' (in ctor parent isn't already assigned)
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
Private Overloads Sub OnParentChanged(sender As Object, e As EventArgs)
Parent.Controls.Add(_suggLb)
Parent.Controls.SetChildIndex(_suggLb, 0)
_suggLb.Top = Top + Height - 3
_suggLb.Left = Left + 3
_suggLb.Width = Width - 20
_suggLb.Font = New Font("Segoe UI", 9)
End Sub
Protected Overrides Sub OnLocationChanged(e As EventArgs)
MyBase.OnLocationChanged(e)
_suggLb.Top = Top + Height - 3
_suggLb.Left = Left + 3
End Sub
Protected Overrides Sub OnSizeChanged(e As EventArgs)
MyBase.OnSizeChanged(e)
_suggLb.Width = Width - 20
End Sub
#End Region
#Region "visibility of suggest box"
Protected Overrides Sub OnLostFocus(e As EventArgs)
' _suggLb can only getting focused by clicking (because TabStop is off)
' --> click-eventhandler 'SuggLbOnClick' is called
If Not _suggLb.Focused Then
HideSuggBox()
End If
MyBase.OnLostFocus(e)
End Sub
Private Sub SuggLbOnClick(sender As Object, eventArgs As EventArgs)
Text = _suggLb.Text
Focus()
End Sub
Private Sub HideSuggBox()
_suggLb.Visible = False
End Sub
Protected Overrides Sub OnDropDown(e As EventArgs)
HideSuggBox()
MyBase.OnDropDown(e)
End Sub
#End Region
#Region "keystroke events"
''' <summary>
''' if the suggest-ListBox is visible some keystrokes
''' should behave in a custom way
''' </summary>
''' <param name="e"></param>
Protected Overrides Sub OnPreviewKeyDown(e As PreviewKeyDownEventArgs)
If Not _suggLb.Visible Then
MyBase.OnPreviewKeyDown(e)
Return
End If
Select Case e.KeyCode
Case Keys.Down
If _suggLb.SelectedIndex < _suggBindingList.Count - 1 Then
_suggLb.SelectedIndex += 1
End If
Return
Case Keys.Up
If _suggLb.SelectedIndex > 0 Then
_suggLb.SelectedIndex -= 1
End If
Return
Case Keys.Enter
Text = _suggLb.Text
[Select](0, Text.Length)
_suggLb.Visible = False
'Mika
Dim myObject As Form1 = New Form1()
myObject.SearchByName(Text)
'Mika
Return
Case Keys.Escape
HideSuggBox()
Return
End Select
MyBase.OnPreviewKeyDown(e)
End Sub
Private Shared ReadOnly KeysToHandle As List(Of Keys) = New List(Of Keys) From {Keys.Down, Keys.Up, Keys.Enter, Keys.Escape}
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
' the keysstrokes of our interest should not be processed be base class:
If _suggLb.Visible AndAlso KeysToHandle.Contains(keyData) Then
Return True
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
#End Region
End Class
End Namespace
I have implemented a LongListSelector for my Windows Phone 7 app. However when I tap an item it doesn't navigate to the desired page. Does anyone know why and how this can be fixed? Below is my code. Each page has it's own uri and I want to navigate to different pages.
All help would be very much appreciated.
Many thanks
Code:
Imports System.Linq
Imports Microsoft.Phone.Controls
Partial Public Class Victoria_line
Inherits PhoneApplicationPage
Public Sub New()
InitializeComponent()
Dim source As New List(Of JumpDemo)()
source.Add(New JumpDemo() With { _
.Name = "Blackhorse Road", _
.FareZone = "Fare zone 3", _
.GroupBy = "b", _
.Link = "/Lines and Stations/Victoria/Blackhorse_Road_(Victoria).xaml" _
})
source.Add(New JumpDemo() With { _
.Name = "Warren Street", _
.FareZone = "Fare zone 1", _
.GroupBy = "w", _
.Link = "/Lines and Stations/Victoria/Warren_Street_(Victoria).xaml" _
})
Dim MygroupBy = From jumpdemo In source _
Group jumpdemo By jumpdemo.GroupBy Into c = Group _
Order By GroupBy _
Select New _
Group(Of JumpDemo)(GroupBy, c)
Me.Victoria_line.ItemsSource = MygroupBy
End Sub
Private Sub Victoria_line_SelectionChanged(ByVal sender As Object, ByVal e As SelectionChangedEventArgs)
If Victoria_line.SelectedItem = Nothing Then
Return
End If
Dim addressString As String = "/StationPage.xaml"
Dim pageUri As Uri = New Uri(addressString, UriKind.Relative)
NavigationService.Navigate(pageUri)
' Reset selected item to -1 (no selection)
Victoria_line.SelectedItem = Nothing
End Sub
End Class
Public Class Group(Of T)
Implements IEnumerable(Of T)
Public Sub New(name As String, items As IEnumerable(Of T))
Me.Title = name
Me.Items = New List(Of T)(items)
End Sub
Public Overrides Function Equals(obj As Object) As Boolean
Dim that As Group(Of T) = TryCast(obj, Group(Of T))
Return (that IsNot Nothing) AndAlso (Me.Title.Equals(that.Title))
End Function
Public Property Title() As String
Get
Return m_Title
End Get
Set(value As String)
m_Title = value
End Set
End Property
Private m_Title As String
Public Property Items() As IList(Of T)
Get
Return m_Items
End Get
Set(value As IList(Of T))
m_Items = value
End Set
End Property
Private m_Items As IList(Of T)
Public Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator
Return Me.Items.GetEnumerator()
End Function
Private Function System_Collections_IEnumerable_GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
Return Me.Items.GetEnumerator()
End Function
End Class
Public Class Victoria
Public Property Name() As String
Get
Return m_Name
End Get
Set(value As String)
m_Name = value
End Set
End Property
Private m_Name As String
Public Property FareZone() As String
Get
Return m_FareZone
End Get
Set(value As String)
m_FareZone = value
End Set
End Property
Private m_FareZone As String
Public Property GroupBy() As String
Get
Return m_GroupBy
End Get
Set(value As String)
m_GroupBy = value
End Set
End Property
Private m_GroupBy As String
Public Property Link() As Uri
Get
Return m_Link
End Get
Set(value As Uri)
m_Link = value
End Set
End Property
Private m_Link As Uri
End Class
If what you are trying to achieve is navigate to another page when you tap on an item you should just register for the Tap event inside your Item DataTemplate and in the event handler do something like this:
Private Sub Item_Tap(sender As Object, e As GestureEventArgs)
Dim element As FrameworkElement = TryCast(sender, FrameworkElement)
Dim item As JumpDemo = TryCast(element.DataContext, JumpDemo)
Dim addressString As String = item.Link
Dim pageUri As Uri = New Uri(addressString, UriKind.Relative)
NavigationService.Navigate(pageUri)
End Sub
I have a var called as "Cheat_Enabled":
Dim Cheat_Enabled As Boolean
And a Checkbox called as "CheckBox_Cheat" with the tag "Cheat"
Now I want to do a dynamic method to change the value of the var by spliting (or something) the name of the control.
For example, something like this (the code obviouslly don't work):
Private Sub CheckBoxes_CheckedChanged(sender As Object, e As EventArgs) Handles _
CheckBox_Cheat.CheckedChanged
Dim SenderVarEquivalent As Object = _
Me.variables.Find(sender.Tag & "_Enabled")(0)
If sender.Checked Then SenderVarEquivalent = True _
Else SenderVarEquivalent = False
End Sub
' Info:
' Sender.Tag = "Cheat"
' Sender.Name = "CheckBox_Cheat"
' VariableName = "Cheat_Enabled"
I think this can be done with one CType or DirectCast or GetObject but I don't know exactly how to do it.
UPDATE:
This is a similar easy code but instead of converting ControlName to VariableName it is converting the control tag to the ControlName Object of the Checkbox:
Public Class Form1
Dim Cheat_Enabled As Boolean = True
Private Sub CheckBox_Cheat_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox_Cheat.CheckedChanged
CType(Controls("CheckBox" & "_" & sender.tag), CheckBox).Checked = Cheat_Enabled
End Sub
End Class
I hope if I can do the same to CType the control name to catch the variablename and use it, for example like this:
Dim Cheat_Enabled As Boolean
Private Sub CheckBox_Cheat_CheckedChanged(sender As Object, e As EventArgs) Handles CheckBox_Cheat.CheckedChanged
' Sender.name is : "CheckBox_Cheat"
' Sender.tag is : "Cheat"
' Variable name is: "Cheat_Enabled"
If sender.checked Then
CType(Variable(sender.tag & "_Enabled"), Boolean) = True
Else
CType(Variable(sender.tag & "_Enabled"), Boolean) = False
End If
End Sub
In MSDN you can find a VB.Net example how to enumerate all members of a given class:
Imports System
Imports System.Reflection
Imports Microsoft.VisualBasic
Class MyFindMembersClass
Public Shared Sub Main()
Dim objTest As New Object()
Dim objType As Type = objTest.GetType()
Dim arrayMemberInfo() As MemberInfo
Try
'Find all static or public methods in the Object
'class that match the specified name.
arrayMemberInfo = objType.FindMembers(MemberTypes.Method, _
BindingFlags.Public Or BindingFlags.Static _
Or BindingFlags.Instance, _
New MemberFilter(AddressOf DelegateToSearchCriteria), _
"ReferenceEquals")
Dim index As Integer
For index = 0 To arrayMemberInfo.Length - 1
Console.WriteLine("Result of FindMembers -" + ControlChars.Tab + _
arrayMemberInfo(index).ToString() + ControlChars.Cr)
Next index
Catch e As Exception
Console.WriteLine("Exception : " + e.ToString())
End Try
End Sub 'Main
Public Shared Function DelegateToSearchCriteria _
(ByVal objMemberInfo As MemberInfo, _
ByVal objSearch As Object) As Boolean
' Compare the name of the member function with the filter criteria.
If objMemberInfo.Name.ToString() = objSearch.ToString() Then
Return True
Else
Return False
End If
End Function 'DelegateToSearchCriteria
End Class 'MyFindMembersClass
Another alternative would be to put all your boolean variables into one Dictionary object. This would allow you to access the boolean values "by name" without using Reflection.
Example for illustration:
Imports System.Collections.Generic
Module vbModule
Class Example
Private _dictionary
Public Sub New()
' Allocate and populate the field Dictionary.
Me._dictionary = New Dictionary(Of String, Boolean)
Me._dictionary.Add("v1", False)
Me._dictionary.Add("v2", True)
End Sub
Public Function GetValue(name as String) As Boolean
' Return value from private Dictionary.
Return Me._dictionary.Item(name)
End Function
Public Sub SetValue(name as String, val as Boolean)
Me._dictionary.Item(name) = val
End Sub
End Class
Sub Main()
' Allocate an instance of the class.
Dim example As New Example
' Write a value from the class.
Console.WriteLine(example.GetValue("v1"))
Console.WriteLine(example.GetValue("v2"))
example.SetValue("v1", true)
Console.WriteLine(example.GetValue("v1"))
End Sub
End Module
I have a webbrowser control on my form, when I navigate to a certain page it opens a popup which opens the page in the current default browser for windows, in this case IE. I would like to access the source code for this page. I dont want to close it, I just want to grab the html.
Thanks for your help.
Edit:
Slution:
eWebbrowser.vb :
Imports System
Imports System.Text
Imports System.Windows.Forms
Imports System.ComponentModel
Imports System.Collections.Generic
Imports System.Runtime.InteropServices
Imports System.Security.Permissions
<PermissionSet(SecurityAction.Demand, Name:="FullTrust")> _
<System.Runtime.InteropServices.ComVisibleAttribute(True)> _
Public Class eWebbrowser
Inherits System.Windows.Forms.WebBrowser
#Region " COM Imports Etc..."
<StructLayout(LayoutKind.Sequential)> _
Public Structure OLECMDTEXT
Public cmdtextf As UInt32
Public cwActual As UInt32
Public cwBuf As UInt32
Public rgwz As Char
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure OLECMD
Public cmdID As Long
Public cmdf As UInt64
End Structure
' Interop - IOleCommandTarget (See MSDN - http://support.microsoft.com/?kbid=311288)
<ComImport(), Guid("b722bccb-4e68-101b-a2bc-00aa00404770"), _
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface IOleCommandTarget
Sub QueryStatus(ByRef pguidCmdGroup As Guid, ByVal cCmds As UInt32, _
<MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> ByVal prgCmds As OLECMD, _
ByRef pCmdText As OLECMDTEXT)
Sub Exec(ByRef pguidCmdGroup As Guid, ByVal nCmdId As Long, _
ByVal nCmdExecOpt As Long, ByRef pvaIn As Object, _
ByRef pvaOut As Object)
End Interface
Private cmdGUID As New Guid(&HED016940, -17061, _
&H11CF, &HBA, &H4E, &H0, &HC0, &H4F, &HD7, &H8, &H16)
#Region " Commands Enumeration "
'There are a ton of ole commands, we are only using a couple, msdn research will
'allow you to figure out which ones you want to use.
Enum oCommands As Long
Options
Find = 1
ViewSource = 2
'////////////////////////////////////////
ID_FILE_SAVEAS = 32771
ID_FILE_PAGESETUP = 32772
ID_FILE_IMPORTEXPORT = 32774
ID_FILE_PRINTPREVIEW = 32776
ID_FILE_NEWIE = 32779
ID_FILE_NEWMAIL = 32780
PID_FILE_NEWINTERNETCALL = 32781
ID_FILE_ADDTRUST = 32782
ID_FILE_ADDLOCAL = 32783
DLCTL_BGSOUNDS = &H40
DLCTL_DLIMAGES = &H10
DLCTL_DOWNLOADONLY = &H800
DLCTL_FORCEOFFLINE = &H10000000
DLCTL_NO_BEHAVIORS = &H800
DLCTL_NO_CLIENTPULL = &H20000000
DLCTL_NO_DLACTIVEXCTLS = &H400
DLCTL_NO_FRAMEDOWNLOAD = &H1000
DLCTL_NO_JAVA = &H100
DLCTL_NO_METACHARSET = &H10000
DLCTL_NO_RUNACTIVEXCTLS = &H200
DLCTL_NO_SCRIPTS = &H80
'DLCTL_OFFLINE DLCTL_OFFLINEIFNOTCONNECTED
DLCTL_OFFLINEIFNOTCONNECTED = &H80000000
DLCTL_PRAGMA_NO_CACHE = &H4000
DLCTL_RESYNCHRONIZE = &H2000
DLCTL_SILENT = &H40000000
DLCTL_URL_ENCODING_DISABLE_UTF8 = &H20000
DLCTL_URL_ENCODING_ENABLE_UTF8 = &H40000
DLCTL_VIDEOS = &H20
End Enum
#End Region
#End Region
'Just a little easier way to get at it.
Public ReadOnly Property CurrentURL() As String
Get
Return Me.Document.Url.ToString
End Get
End Property
Public Sub New()
MyBase.New()
End Sub
#Region " Dialogs "
Public Sub ShowOpen()
Dim cdlOpen As New OpenFileDialog
Try
cdlOpen.Filter = "HTML Files (*.htm)|*.htm|HTML Files (*.html)|*.html|TextFiles" & _
"(*.txt)|*.txt|Gif Files (*.gif)|*.gif|JPEG Files (*.jpg)|*.jpeg|" & _
"PNG Files (*.png)|*.png|Art Files (*.art)|*.art|AU Fles (*.au)|*.au|" & _
"AIFF Files (*.aif|*.aiff|XBM Files (*.xbm)|*.xbm|All Files (*.*)|*.*"
cdlOpen.Title = " Open File "
cdlOpen.ShowDialog()
If cdlOpen.FileName > Nothing Then
Me.Navigate(cdlOpen.FileName)
End If
Catch ex As Exception
Throw New Exception(ex.Message.ToString)
End Try
End Sub
Public Sub ShowSource()
Dim cmdt As IOleCommandTarget
Dim o As Object = Nothing
Dim oIE As Object = Nothing
Try
cmdt = CType(Me.Document.DomDocument, IOleCommandTarget)
cmdt.Exec(cmdGUID, oCommands.ViewSource, 1, o, o)
Catch ex As Exception
Throw New Exception(ex.Message.ToString, ex.InnerException)
Finally
cmdt = Nothing
End Try
End Sub
Public Sub ShowFindDialog()
Dim cmdt As IOleCommandTarget
Dim o As Object = Nothing
Dim oIE As Object = Nothing
Try
cmdt = CType(Me.Document.DomDocument, IOleCommandTarget)
cmdt.Exec(cmdGUID, oCommands.Find, 0, o, o)
Catch ex As Exception
Throw New Exception(ex.Message.ToString, ex.InnerException)
Finally
cmdt = Nothing
End Try
End Sub
Public Sub AddToFavorites(Optional ByVal strURL As String = "", Optional ByVal strTitle As String = "")
Dim oHelper As Object = Nothing
Try
oHelper = New ShellUIHelper
oHelper.AddFavorite(Me.Document.Url.ToString, Me.DocumentTitle.ToString)
Catch ex As Exception
Throw New Exception(ex.Message.ToString)
End Try
If oHelper IsNot Nothing AndAlso Marshal.IsComObject(oHelper) Then
Marshal.ReleaseComObject(oHelper)
End If
End Sub
Public Sub ShowOrganizeFavorites()
'Organize Favorites
Dim helper As Object = Nothing
Try
helper = New ShellUIHelper()
helper.ShowBrowserUI("OrganizeFavorites", 0)
Finally
If helper IsNot Nothing AndAlso Marshal.IsComObject(helper) Then
Marshal.ReleaseComObject(helper)
End If
End Try
End Sub
Public Sub SendToDesktop()
'Shortcut to desktop
Dim helper As Object = Nothing
Try
helper = New ShellUIHelper()
helper.AddDesktopComponent(Me.Document.Url.ToString, "website")
Finally
If helper IsNot Nothing AndAlso Marshal.IsComObject(helper) Then
Marshal.ReleaseComObject(helper)
End If
End Try
End Sub
''' <summary>
''' This Will launch the internet option dialog.
''' </summary>
''' <remarks></remarks>
Public Sub ShowInternetOptions()
Shell("rundll32.exe shell32.dll,Control_RunDLL inetcpl.cpl,,0", vbNormalFocus)
End Sub
Public Sub ShowPrivacyReport()
Shell("rundll32.exe shell32.dll,Control_RunDLL inetcpl.cpl,,2", vbNormalFocus)
End Sub
#End Region
#Region " Extended "
<ComImport(), _
Guid("34A715A0-6587-11D0-924A-0020AFC7AC4D"), _
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch), _
TypeLibType(TypeLibTypeFlags.FHidden)> _
Public Interface DWebBrowserEvents2
<DispId(250)> _
Sub BeforeNavigate2(<[In](), MarshalAs(UnmanagedType.IDispatch)> ByVal pDisp As Object, _
<InAttribute(), MarshalAs(UnmanagedType.BStr)> ByRef URL As String, _
<InAttribute()> ByRef flags As Object, _
<InAttribute(), MarshalAs(UnmanagedType.BStr)> ByRef targetFrameName As String, _
<InAttribute()> ByRef postdata As Object, _
<InAttribute(), MarshalAs(UnmanagedType.BStr)> ByRef headers As String, _
<InAttribute(), OutAttribute()> ByRef cancel As Boolean)
'Note: Postdata is a SafeArray but for some reason, if I do a proper declaration, the event will not be raised:
'<[In](), MarshalAs(UnmanagedType.SafeArray, safearraysubtype:=VarEnum.VT_UI1)> ByRef postdata() As Byte, _
<DispId(273)> _
Sub NewWindow3(<InAttribute(), MarshalAs(UnmanagedType.IDispatch)> ByVal pDisp As Object, _
<InAttribute(), OutAttribute()> ByRef cancel As Boolean, _
<InAttribute()> ByRef Flags As Object, _
<InAttribute(), MarshalAs(UnmanagedType.BStr)> ByRef UrlContext As String, _
<InAttribute(), MarshalAs(UnmanagedType.BStr)> ByRef Url As String)
End Interface
Public Enum NWMF
NWMF_UNLOADING = &H1&
NWMF_USERINITED = &H2&
NWMF_FIRST_USERINITED = &H4&
NWMF_OVERRIDEKEY = &H8&
NWMF_SHOWHELP = &H10&
NWMF_HTMLDIALOG = &H20&
NWMF_FROMPROXY = &H40&
End Enum
Private cookie As AxHost.ConnectionPointCookie
Private wevents As WebBrowserExtendedEvents
'This method will be called to give you a chance to create your own event sink
Protected Overrides Sub CreateSink()
'MAKE SURE TO CALL THE BASE or the normal events won't fire
MyBase.CreateSink()
wevents = New WebBrowserExtendedEvents(Me)
cookie = New AxHost.ConnectionPointCookie(Me.ActiveXInstance, wevents, GetType(DWebBrowserEvents2))
End Sub
Protected Overrides Sub DetachSink()
If Not cookie Is Nothing Then
cookie.Disconnect()
cookie = Nothing
End If
MyBase.DetachSink()
End Sub
'This new event will fire when the page is navigating
Public Delegate Sub WebBrowserNavigatingExtendedEventHandler(ByVal sender As Object, ByVal e As WebBrowserNavigatingExtendedEventArgs)
Public Event NavigatingExtended As WebBrowserNavigatingExtendedEventHandler
'This event will fire when a new window is about to be opened
Public Delegate Sub WebBrowserNewWindowExtendedEventHandler(ByVal sender As Object, ByVal e As WebBrowserNewWindowExtendedEventArgs)
Public Event NewWindowExtended As WebBrowserNewWindowExtendedEventHandler
Protected Friend Sub OnNavigatingExtended(ByVal Url As String, ByVal Frame As String, ByVal Postdata As Byte(), ByVal Headers As String, ByRef Cancel As Boolean)
Dim e As WebBrowserNavigatingExtendedEventArgs = New WebBrowserNavigatingExtendedEventArgs(Url, Frame, Postdata, Headers)
RaiseEvent NavigatingExtended(Me, e)
Cancel = e.Cancel
End Sub
Protected Friend Sub OnNewWindowExtended(ByVal Url As String, ByRef Cancel As Boolean, ByVal Flags As NWMF, ByVal UrlContext As String)
Dim e As WebBrowserNewWindowExtendedEventArgs = New WebBrowserNewWindowExtendedEventArgs(Url, UrlContext, Flags)
RaiseEvent NewWindowExtended(Me, e)
Cancel = e.Cancel
End Sub
Public Overloads Sub Navigate2(ByVal URL As String)
MyBase.Navigate(URL)
End Sub
#End Region
#Region " Extended Event Classes "
'This class will capture events from the WebBrowser
Friend Class WebBrowserExtendedEvents
Inherits System.Runtime.InteropServices.StandardOleMarshalObject
Implements DWebBrowserEvents2
Private m_Browser As eWebbrowser
Public Sub New(ByVal browser As eWebbrowser)
m_Browser = browser
End Sub
'Implement whichever events you wish
Public Sub BeforeNavigate2(ByVal pDisp As Object, ByRef URL As String, ByRef flags As Object, ByRef targetFrameName As String, ByRef postData As Object, ByRef headers As String, ByRef cancel As Boolean) Implements DWebBrowserEvents2.BeforeNavigate2
m_Browser.OnNavigatingExtended(URL, targetFrameName, CType(postData, Byte()), headers, cancel)
End Sub
Public Sub NewWindow3(ByVal pDisp As Object, ByRef Cancel As Boolean, ByRef Flags As Object, ByRef UrlContext As String, ByRef Url As String) Implements DWebBrowserEvents2.NewWindow3
m_Browser.OnNewWindowExtended(Url, Cancel, CType(Flags, NWMF), UrlContext)
End Sub
End Class
Public Class WebBrowserNewWindowExtendedEventArgs
Inherits CancelEventArgs
Private m_Url As String
Private m_UrlContext As String
Private m_Flags As NWMF
Public ReadOnly Property Url() As String
Get
Return m_Url
End Get
End Property
Public ReadOnly Property UrlContext() As String
Get
Return m_UrlContext
End Get
End Property
Public ReadOnly Property Flags() As NWMF
Get
Return m_Flags
End Get
End Property
Public Sub New(ByVal url As String, ByVal urlcontext As String, ByVal flags As NWMF)
m_Url = url
m_UrlContext = urlcontext
m_Flags = flags
End Sub
End Class
'First define a new EventArgs class to contain the newly exposed data
Public Class WebBrowserNavigatingExtendedEventArgs
Inherits CancelEventArgs
Private m_Url As String
Private m_Frame As String
Private m_Postdata() As Byte
Private m_Headers As String
Public ReadOnly Property Url() As String
Get
Return m_Url
End Get
End Property
Public ReadOnly Property Frame() As String
Get
Return m_Frame
End Get
End Property
Public ReadOnly Property Headers() As String
Get
Return m_Headers
End Get
End Property
Public ReadOnly Property Postdata() As String
Get
Return PostdataToString(m_Postdata)
End Get
End Property
Public ReadOnly Property PostdataByte() As Byte()
Get
Return m_Postdata
End Get
End Property
Public Sub New(ByVal url As String, ByVal frame As String, ByVal postdata As Byte(), ByVal headers As String)
m_Url = url
m_Frame = frame
m_Postdata = postdata
m_Headers = headers
End Sub
Private Function PostdataToString(ByVal p() As Byte) As String
'not sexy but it works...
Dim tabpd() As Byte, bstop As Boolean = False, stmp As String = "", i As Integer = 0
tabpd = p
If tabpd Is Nothing OrElse tabpd.Length = 0 Then
Return ""
Else
For i = 0 To tabpd.Length - 1
stmp += ChrW(tabpd(i))
Next
stmp = Replace(stmp, ChrW(13), "")
stmp = Replace(stmp, ChrW(10), "")
stmp = Replace(stmp, ChrW(0), "")
End If
If stmp = Nothing Then
Return ""
Else
Return stmp
End If
End Function
End Class
#End Region
<ComImport(), Guid("64AB4BB7-111E-11D1-8F79-00C04FC2FBE1")> _
Public Class ShellUIHelper
'
End Class
End Class
form load:
Public WithEvents wb As eWebbrowser
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim brws As New eWebbrowser
wb = brws
End Sub
Events:
Private Sub wb_NewWindow(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles wb.NewWindow
e.Cancel = True
End Sub
The New Event:
Private Sub wb_NewWindowExtended(ByVal sender As Object, ByVal e As eWebbrowser.WebBrowserNewWindowExtendedEventArgs) Handles wb.NewWindowExtended
e.Cancel = True
Dim url As String = e.Url
msgbox(url) //This Is The Url!!
End Sub
How can I create a nullable numeric optional parameter in VB.NET?
EDIT: this should be possible in VB.NET 10 according to this blog post. If you're using it then you could have:
Public Sub DoSomething(Optional ByVal someInteger As Integer? = Nothing)
Console.WriteLine("Result: {0} - {1}", someInteger.HasValue, someInteger)
End Sub
' use it
DoSomething(Nothing)
DoSomething(20)
For versions other than VB.NET 10:
Your request is not possible. You should either use an optional parameter, or a nullable. This signature is invalid:
Public Sub DoSomething(Optional ByVal someInteger As Nullable(Of Integer) _
= Nothing)
You would get this compile error: "Optional parameters cannot have structure types."
If you're using a nullable then set it to Nothing if you don't want to pass it a value. Choose between these options:
Public Sub DoSomething(ByVal someInteger As Nullable(Of Integer))
Console.WriteLine("Result: {0} - {1}", someInteger.HasValue, someInteger)
End Sub
or
Public Sub DoSomething(Optional ByVal someInteger As Integer = 42)
Console.WriteLine("Result: {0}", someInteger)
End Sub
You can't, so you'll have to make do with an overload instead:
Public Sub Method()
Method(Nothing) ' or Method(45), depending on what you wanted default to be
End Sub
Public Sub Method(value as Nullable(Of Integer))
' Do stuff...
End Sub
You can also use an object:
Public Sub DoSomething(Optional ByVal someInteger As Object = Nothing)
If someInteger IsNot Nothing Then
... Convert.ToInt32(someInteger)
End If
End Sub
I figure it out in VS2012 version like
Private _LodgingItemId As Integer?
Public Property LodgingItemId() As Integer?
Get
Return _LodgingItemId
End Get
Set(ByVal Value As Integer?)
_LodgingItemId = Value
End Set
End Property
Public Sub New(ByVal lodgingItem As LodgingItem, user As String)
Me._LodgingItem = lodgingItem
If (lodgingItem.LodgingItemId.HasValue) Then
LoadLodgingItemStatus(lodgingItem.LodgingItemId)
Else
LoadLodgingItemStatus()
End If
Me._UpdatedBy = user
End Sub
Private Sub LoadLodgingItemStatus(Optional ByVal lodgingItemId As Integer? = Nothing)
''''statement
End Sub