I am developing a WinForms application and I want a ListBox (or a control which provides list of strings) such that when the user hovers the mouse over an item it will show a delete sign for that particular item.
Is there any control available for WinForms to do this?
Setting the ListBox DrawMode to OwnerDrawFixed (or OwnerDrawVariable), you can just handle this yourself with the Mouse events:
Public Class Form1
Private _MouseIndex As Integer = -1
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
ListBox1.Items.Add("String #1")
ListBox1.Items.Add("String #2")
End Sub
Private Sub ListBox1_DrawItem(ByVal sender As Object, ByVal e As DrawItemEventArgs) Handles ListBox1.DrawItem
e.DrawBackground()
If e.Index > -1 Then
Dim brush As Brush = SystemBrushes.WindowText
If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then
brush = SystemBrushes.HighlightText
End If
e.Graphics.DrawString(ListBox1.Items(e.Index), e.Font, brush, e.Bounds.Left + 20, e.Bounds.Top)
If e.Index = _MouseIndex Then
e.Graphics.DrawString("X", e.Font, brush, e.Bounds.Left + 2, e.Bounds.Top)
End If
End If
End Sub
Private Sub ListBox1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles ListBox1.MouseDown
If _MouseIndex > -1 AndAlso ListBox1.IndexFromPoint(e.Location) = _MouseIndex AndAlso e.Location.X < 20 Then
Dim index As Integer = _MouseIndex
If MessageBox.Show("Do you want to delete this item?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes Then
ListBox1.Items.RemoveAt(index)
ListBox1.Invalidate()
End If
End If
End Sub
Private Sub ListBox1_MouseLeave(ByVal sender As Object, ByVal e As EventArgs) Handles ListBox1.MouseLeave
If _MouseIndex <> -1 Then
_MouseIndex = -1
ListBox1.Invalidate()
End If
End Sub
Private Sub ListBox1_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles ListBox1.MouseMove
Dim index As Integer = ListBox1.IndexFromPoint(e.Location)
If index <> _MouseIndex Then
_MouseIndex = index
ListBox1.Invalidate()
End If
End Sub
End Class
Refactor as needed.
Related
I want to Drag Move a userControl which is in a canvas(named as grd) and that canvas is in a larger canvas on which there are a lot of other controls. I am using this code, but it does not work. I am making mouseDown and MouseUpevents of userControl and a MouseMve event of the larger canvas which has a lot of controls.
Where is the problem?
Dim _pressed As Boolean = False
Dim grd As Canvas
Dim mp As Point
Private Sub DeviceIcon_MouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs)
_pressed = True
grd = sender
mp = mousePosition
End Sub
Private Sub DeviceIcon_MouseLeftButtonUp(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs)
_pressed = False
End Sub
Private Sub gridimgFloor_MouseMove(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseEventArgs) Handles gridimgFloor.MouseMove
If _pressed = False Then Exit Sub
Dim nmp As Point = mousePosition
Dim _x As Integer = nmp.X - mp.X
Dim _y As Integer = nmp.Y - mp.Y
Dim thk As Thickness = grd.Margin
thk.Left = thk.Left + _x
thk.Top = thk.Top + _y
grd.Margin = thk
mp = nmp
End Sub
You should use e.GetPosition(parentControl) to get the position from the event args.
I am trying to clear session cookies in a WPF WebBrowser. This method
Public Const INTERNET_OPTION_END_BROWSER_SESSION As Integer = 42
<DllImport("wininet.dll", SetLastError:=True)>
Public Function InternetSetOption(ByVal hInternet As IntPtr, ByVal dwOption As Integer, ByVal lpBuffer As IntPtr, ByVal lpdwBufferLength As Integer) As Boolean
End Function
described here How to clear System.Windows.Forms.WebBrowser session data? works for our WinForms applications, but not for WPF.
Any ideas?
Thanks
Turns out the answer is to ensure that the WebBrowser object is created each time the page is loaded.
As the WebBrowser object is not considered to be a control I created a ScrollViewer at initialisation then added the WebBrowser to the ScrollViewer on the loaded event.
It now works perfectly
for Faber75
Imports System.ComponentModel
Class Website_Login_Page
Private LoginBrowser As WebBrowser
Private Sub Website_Login_Page_Initialized(sender As Object, e As System.EventArgs) Handles Me.Initialized
Try
Website_Login_Grid.Background = New SolidColorBrush(Colors.White)
For i As Integer = 0 To 1
Dim vRow As New RowDefinition
If i = 0 Then
vRow.Height = New GridLength(35, GridUnitType.Star)
Else
vRow.Height = New GridLength(35)
End If
Website_Login_Grid.RowDefinitions.Add(vRow)
Next
Dim SV As New ScrollViewer
With SV
.VerticalScrollBarVisibility = ScrollBarVisibility.Auto
.Name = "Website_Login_SV"
End With
RegisterControl(Website_Login_Grid, SV)
'Cookies are not removed if the WebBrowser object is not created each time the page is loaded!
' LoginBrowser = New WebBrowser
Grid.SetRow(SV, 0)
Website_Login_Grid.Children.Add(SV)
Dim DP As DockPanel = PageStatusBarDP(Website_Login_Grid)
Grid.SetRow(DP, 1)
Website_Login_Grid.Children.Add(DP)
Catch ex As Exception
EmailError(ex)
End Try
End Sub
Private Sub Website_Login_Page_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
Try
If LoginBrowser Is Nothing Then
LoginBrowser = New WebBrowser
End If
Dim SV As ScrollViewer = Website_Login_Grid.FindName("Website_Login_SV")
SV.Content = LoginBrowser
AddHandler LoginBrowser.Navigating, AddressOf WebBrowser_Loading
AddHandler LoginBrowser.LoadCompleted, AddressOf WebBrowser_Loaded
AddHandler LoginBrowser.Navigated, AddressOf WebBrowser_Navigated
If InternetSetOption(IntPtr.Zero, INTERNET_OPTION_END_BROWSER_SESSION, IntPtr.Zero, 0) = False Then
MessageBox.Show("Returned False")
End If
With LoginBrowser
.Navigate(New Uri("https://website.com"))
End With
Catch ex As Exception
EmailError(ex)
End Try
End Sub
Private Sub Website_Login_Page_Unloaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Unloaded
Try
If Not LoginBrowser Is Nothing Then
RemoveHandler LoginBrowser.Navigating, AddressOf WebBrowser_Loading
RemoveHandler LoginBrowser.LoadCompleted, AddressOf WebBrowser_Loaded
RemoveHandler LoginBrowser.Navigated, AddressOf WebBrowser_Navigated
LoginBrowser = Nothing
End If
GC.GetTotalMemory(True)
Catch ex As Exception
EmailError(ex)
End Try
End Sub
Private Sub WebBrowser_Loading(ByVal sender As Object, ByVal e As NavigatingCancelEventArgs)
PageStatusBarLoading(Website_Login_Grid)
PageStatusBarRightChangeText(Website_Login_Grid, "Loading... Please wait...")
End Sub
Private Sub WebBrowser_Loaded(ByVal sender As Object, ByVal e As NavigationEventArgs)
Dim vDoc As Object = LoginBrowser.Document
Dim vTitle As String = vDoc.Title
PageStatusBarLoaded(Website_Login_Grid, vTitle)
PageStatusBarRightChangeText(Website_Login_Grid, "Loaded")
End Sub
Private Sub WebBrowser_Navigated(ByVal sender As Object, ByVal e As NavigationEventArgs)
Dim vDoc As Object = LoginBrowser.Document
Dim vTitle As String = vDoc.Title
PageStatusBarLoaded(Website_Login_Grid, vTitle)
PageStatusBarRightChangeText(Website_Login_Grid, "Loaded")
End Sub
End Class
The following is the code which I am using for creating a two dimensional array
Public Class frmGrades
Private Score As Dictionary(Of String, String) = New Dictionary(Of String, String)
Private Sub cmdApply_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdApply.Click
Static intNumber As Integer
ReDim Preserve Score(1, intNumber)
Score(0, intNumber) = txtStudent.Text
Score(1, intNumber) = txtGrade.Text
hsbStudent.Maximum = intNumber
hsbStudent.Value = intNumber
intNumber = intNumber + 1
txtGrade.Clear()
txtStudent.Clear()
txtStudent.Focus()
End Sub
Private Sub hsbStudent_Scroll(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles hsbStudent.Scroll
txtStudent.Text = Score(0, hsbStudent.Value)
txtGrade.Text = Score(1, hsbStudent.Value)
End Sub
Private Sub cmdFirst_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdFirst.Click
txtStudent.Text = Score(0, hsbStudent.Minimum)
txtGrade.Text = Score(1, hsbStudent.Minimum)
End Sub
Private Sub cmdLast_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdLast.Click
txtStudent.Text = Score(0, hsbStudent.Maximum)
txtGrade.Text = Score(1, hsbStudent.Maximum)
End Sub
**Private Sub CmdEdit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CmdEdit.Click
If Score.ContainsKey(txtStudent.Text) Then
Score.Item(txtStudent.Text) = txtGrade.Text
Else
Score.Add(txtStudent.Text, txtGrade.Text)
End If
End Sub
End Class**
Now I would like to edit the grade text box which should also change the grade in the array. Any idea on how could this be done.
UPDATE:
OK, I see the code has a little more now and the problem is more clear as well as the need for a different approach. I rewrote your code. See if this works for you:
Public Class frmGrades
Public Class StudentGrade
Public Name As String
Public Grade As String
End Class
Private Score As List(Of StudentGrade) = New List(Of StudentGrade)
Private Sub cmdApply_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdApply.Click
AddStudent()
End Sub
Private Sub hsbStudent_Scroll(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs) Handles hsbStudent.Scroll
Update(hsbStudent.Value - 1) 'lists are zero-based
End Sub
Private Sub cmdFirst_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdFirst.Click
Update(0)
End Sub
Private Sub cmdLast_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdLast.Click
Update(hsbStudent.Maximum - 1)
End Sub
Private Sub AddStudent()
Dim nm As New StudentGrade
nm.Name = txtStudent.Text
nm.Grade = txtGrade.Text
Score.Add(nm)
hsbStudent.Minimum = 1
hsbStudent.Maximum = Score.Count
hsbStudent.Value = Score.Count
txtGrade.Clear()
txtStudent.Clear()
txtStudent.Focus()
End Sub
Private Sub Update(i As Integer)
txtStudent.Text = Score(i).Name
txtGrade.Text = Score(i).Grade
End Sub
Private Sub CmdEdit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CmdEdit.Click
Dim index As Integer = -1, cnt As Integer = 0
For Each nm As StudentGrade In Score
If nm.Name.ToLower = txtStudent.Text.ToLower Then
index = cnt
Exit For
End If
cnt += 1
Next
If index = -1 Then
AddStudent()
Else
Score(index).Name = txtStudent.Text
Score(index).Grade = txtGrade.Text
hsbStudent.Value = index + 1
End If
End Sub
End Class
With this code you can expand the class StudentGrade to contain whatever you need to store. The list, contrary to dictionary, allow you to use index values as well.
Here is my code and I am able to add the text by defining some font properties but I want to add this using Font dialog.Can anyone help me regarding this issue.
Public Class Form1
Dim pic_font As New Font("Arial Black", 40, FontStyle.Regular, GraphicsUnit.Pixel)
Dim bm As Bitmap = New Bitmap(100, 100)
Dim strText As String = "Diver Dude"
Dim szText As New SizeF
Dim ptText As New Point(125, 125)
Dim ptsText() As PointF
Dim MovingOffset As PointF
Dim ptsTextPen As Pen = New Pen(Color.LightSteelBlue, 1)
Dim MouseMoving As Boolean
Dim MouseOver As Boolean
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
Me.SetStyle(ControlStyles.DoubleBuffer, True)
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
PictureBox1.Hide()
bm = Image.FromFile(Application.StartupPath & "\DivePic.bmp")
szText = Me.CreateGraphics.MeasureString(strText, pic_font)
SetptsText()
ptsTextPen.DashStyle = DashStyle.Dot
End Sub
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
'Check if the pointer is over the Text
If IsMouseOverText(e.X - 10, e.Y - 10) Then
MouseMoving = True
'Determine the upper left corner point from where the mouse was clicked
MovingOffset.X = e.X - ptText.X
MovingOffset.Y = e.Y - ptText.Y
Else
MouseMoving = False
End If
End Sub
Private Sub Form1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
'Check if the pointer is over the Text
If IsMouseOverText(e.X - 10, e.Y - 10) Then
If Not MouseOver Then
MouseOver = True
Me.Refresh()
End If
Else
If MouseOver Then
MouseOver = False
Me.Refresh()
End If
End If
If e.Button = Windows.Forms.MouseButtons.Left And MouseMoving Then
ptText.X = CInt(e.X - MovingOffset.X)
ptText.Y = CInt(e.Y - MovingOffset.Y)
Me.Refresh()
End If
End Sub
Private Sub Form1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
MouseMoving = False
Me.Refresh()
End Sub
Public Function IsMouseOverText(ByVal X As Integer, ByVal Y As Integer) As Boolean
'Make a Graphics Path from the rotated ptsText.
Using gp As New GraphicsPath()
gp.AddPolygon(ptsText)
'Convert to Region.
Using TextRegion As New Region(gp)
'Is the point inside the region.
Return TextRegion.IsVisible(X, Y)
End Using
End Using
End Function
Dim tbm As Bitmap
Private Sub Form1_Paint(ByVal sender As Object, _
ByVal e As System.Windows.Forms.PaintEventArgs) _
Handles MyBase.Paint
tbm = CType(bm.Clone, Bitmap)
Dim g As Graphics = Graphics.FromImage(tbm)
Dim mx As Matrix = New Matrix
Dim gpathText As New GraphicsPath
Dim br As SolidBrush = New SolidBrush(Color.FromArgb(tbarTrans.Value, _
KryptonColorButton1.SelectedColor))
SetptsText()
'Smooth the Text
g.SmoothingMode = SmoothingMode.AntiAlias
'Make the GraphicsPath for the Text
Dim emsize As Single = Me.CreateGraphics.DpiY * pic_font.SizeInPoints / 72
gpathText.AddString(strText, pic_font.FontFamily, CInt(pic_font.Style), _
emsize, New RectangleF(ptText.X, ptText.Y, szText.Width, szText.Height), _
StringFormat.GenericDefault)
'Draw a copy of the image to the Graphics Object canvas
g.DrawImage(CType(bm.Clone, Bitmap), 0, 0)
'Rotate the Matrix at the center point
mx.RotateAt(tbarRotate.Value, _
New Point(ptText.X + (szText.Width / 2), ptText.Y + (szText.Height / 2)))
'Get the points for the rotated text bounds
mx.TransformPoints(ptsText)
'Transform the Graphics Object with the Matrix
g.Transform = mx
'Draw the Rotated Text
If chkAddOutline.Checked Then
Using pn As Pen = New Pen(Color.FromArgb(tbarTrans.Value, KryptonColorButton2.SelectedColor), 1)
g.DrawPath(pn, gpathText)
End Using
Else
g.FillPath(br, gpathText)
End If
If CheckBox2.Checked = True Then
Dim p As New Pen(Color.FromArgb(tbarTrans.Value, KryptonColorButton2.SelectedColor), 1)
'draw te hollow outlined text
g.DrawPath(p, gpathText)
'clear the path
gpathText.Reset()
Else
g.FillPath(br, gpathText)
End If
'Draw the box if the mouse is over the Text
If MouseOver Then
g.ResetTransform()
g.DrawPolygon(ptsTextPen, ptsText)
End If
'Draw the whole thing to the form
e.Graphics.DrawImage(tbm, 10, 10)
'tbm.Dispose()
g.Dispose()
mx.Dispose()
br.Dispose()
gpathText.Dispose()
End Sub
Private Sub TrackBar_Scroll(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles tbarRotate.Scroll, tbarTrans.Scroll
lblRotate.Text = tbarRotate.Value
lblOpacity.Text = tbarTrans.Value
Me.Refresh()
End Sub
Sub SetptsText()
'Create a point array of the Text Rectangle
ptsText = New PointF() { _
ptText, _
New Point(CInt(ptText.X + szText.Width), ptText.Y), _
New Point(CInt(ptText.X + szText.Width), CInt(ptText.Y + szText.Height)), _
New Point(ptText.X, CInt(ptText.Y + szText.Height)) _
}
End Sub
Private Sub chkAddOutline_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkAddOutline.CheckedChanged
Me.Refresh()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If FontDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
PictureBox1.Image = Image.FromFile(OpenFileDialog1.FileName)
bm = Image.FromFile(OpenFileDialog1.FileName)
szText = Me.CreateGraphics.MeasureString(strText, pic_font)
SetptsText()
ptsTextPen.DashStyle = DashStyle.Dot
End If
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
tbm.Save(SaveFileDialog1.FileName)
End If
End Sub
End Class
What do you mean.If you mean open a font dialog and select a font from it,here is the code.
' You need Import System.Drawing before your class
' In your class vars section
Dim fd As New FontDialog
'later in your code
' This should be in the code where you call the font dialog
If(fd.ShowDialog() == DialogResults.Ok)
pic_font = fd.Font
End If
What's wrong in my code? It's not updating the TextBox and the ProgressBar while deleting files.
Imports System.Windows.Threading
Imports System.IO
Class MainWindow
Private Sub bt_Click(ByVal sender As Object,
ByVal e As RoutedEventArgs) Handles bt.Click
Dim sb As New System.Text.StringBuilder
Dim files = IO.Directory.EnumerateFiles(
My.Computer.FileSystem.SpecialDirectories.Temp, "*.*",
SearchOption.TopDirectoryOnly)
Dim count = files.Count
pb.Minimum = 0
pb.Maximum = count
For i = 0 To count - 1
Dim f = files(i)
Dispatcher.BeginInvoke(
New Action(Of String, Integer)(
Sub(str, int)
tb.SetValue(TextBox.TextProperty, str)
pb.SetValue(ProgressBar.ValueProperty, int)
End Sub),
DispatcherPriority.Send,
f, i + 1)
Try
File.Delete(f)
Catch ex As Exception
sb.AppendLine(f)
End Try
Dim exceptions = sb.ToString
Stop
Next
End Sub
End Class
I got this working with the BackgroundWorker object. This places your work in a background thread, with calls to update the UI going through the ProgressChanged event. I also used Invoke instead of BeginInvoke within the work loop, which forces the loop to wait for the UI to become updated before it proceeds.
Imports System.ComponentModel
Imports System.IO
Class MainWindow
Private WithEvents bw As New BackgroundWorker
Private Sub Button1_Click(ByVal sender As System.Object,
ByVal e As RoutedEventArgs) Handles btn.Click
pb.Minimum = 0
pb.Maximum = 100
bw.WorkerReportsProgress = True
bw.RunWorkerAsync()
End Sub
Private Sub bw_DoWork(ByVal sender As Object,
ByVal e As DoWorkEventArgs) Handles bw.DoWork
Dim sb As New System.Text.StringBuilder
Dim files = IO.Directory.EnumerateFiles(
My.Computer.FileSystem.SpecialDirectories.Temp, "*.*",
SearchOption.TopDirectoryOnly)
Dim count = files.Count
Me.Dispatcher.BeginInvoke(Sub()
tb.Text = "SOMETHING ELSE"
End Sub)
For i = 0 To count - 1
Dim f = files(i)
Dim myI = i + 1
Me.Dispatcher.Invoke(
Sub()
bw.ReportProgress(CInt((myI / count) * 100), f)
End Sub)
'Try
' File.Delete(f)
'Catch ex As Exception
' sb.AppendLine(f)
'End Try
Dim exceptions = sb.ToString
'Stop
Next
End Sub
Private Sub bw_ProgressChanged(
ByVal sender As Object,
ByVal e As ProgressChangedEventArgs) Handles bw.ProgressChanged
Dim fString As String = TryCast(e.UserState, String)
Me.Dispatcher.BeginInvoke(Sub()
tb.Text = fString
End Sub)
End Sub
End Class