What event would fit when I click the "Restore Down" button in the title bar then it restores down the main form together with the other form with the specific size I declared.
I am new to vb.net and still exploring new functions. Please help!
Apologizes for c# solution, perhaps this will help you to convert it to VB.Net. I don't know any better solution available but this should work.
private FormWindowState? previousWindowState;
protected override void OnSizeChanged(EventArgs e)
{
if (this.Bounds == this.RestoreBounds && previousWindowState.HasValue && previousWindowState.Value == FormWindowState.Maximized)
{
Console.WriteLine("Restored down");
}
previousWindowState = this.WindowState;
base.OnSizeChanged(e);
}
Adapted Srirams answer to vb.net
Private Sub MotionManagerDialog_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SizeChanged
If Me.Bounds.Equals(Me.RestoreBounds) And Not PreviousWindowState.Equals(Nothing) And
PreviousWindowState.Equals(System.Windows.Forms.FormWindowState.Maximized) Then
' Captures restore down action
End If
PreviousWindowState = Me.WindowState
End Sub
To clarify Wylie's answer: You also need to declare PreviousWindowState somewhere:
Dim PreviousWindowState As FormWindowState
Related
I'm developing a WPF application for my company, and everything needs to look the same way corresponding to our company's look. Therefore I have to make a custom folder explorer, which will feature a treeview of the current directory.
In order to make it easier, I've made the following class, which is basically a TreeViewItem that stores a DirectoryInfo and automaticely browses subfolders when expanded (not to browse everything at once and make the software faster). Here is my code :
Private Class TreeViewPlus
Inherits TreeViewItem
Public dir As IO.DirectoryInfo
Public Sub New()
End Sub
Public Sub New(dir As DirectoryInfo)
Me.dir = dir
Try
If Not dir.EnumerateDirectories Is Nothing Then 'If there are subdirectories, I add an empty item to enable the expansion
Me.Items.Add(New TreeViewPlus)
End If
Catch ex As Exception
End Try
End Sub
Private Sub TreeViewPlus_Expanded(sender As Object, e As RoutedEventArgs) Handles Me.Expanded
Me.Items.Clear()
Try
For Each folder In dir.EnumerateDirectories()
Dim item As TreeViewPlus = New TreeViewPlus(folder)
item.Name = Text.RegularExpressions.Regex.Replace(folder.FullName, "[^a-zA-Z0-9]", "")
item.Header = folder.Name
Me.Items.Add(item)
Next
Catch ex As Exception
End Try
End Sub
End Class
And here is the code where I initialize the first directories: (TRV_Arbre is the name of my TreeView)
Sub New()
...
For Each Drive As IO.DriveInfo In IO.DriveInfo.GetDrives
Dim item As TreeViewPlus = New TreeViewPlus(Drive.RootDirectory)
item.Header = Drive.Name
TRV_Arbre.Items.Add(item)
Next
...
End Sub
The Issue I've got is that the first level of items correctly expand, but not the following ones.
See here : https://youtu.be/E6BJbKal5Sk
I've already debugged my code a little, and it correctly creates the different Items.
Can anyone help me for this ? Thanks in advance.
There is a simple way to solve this problem and that is to Override the OnExpanded Sub on the Base TreeViewItem class instead of implementing your own Expanded method. Then in the end you execute MyBase.OnExpanded(e) method which seems to contain the correct update events to send out to whomever listens. In this case your TreeView.
Protected Overrides Sub OnExpanded(e As RoutedEventArgs)
Me.Items.Clear()
Try
For Each folder In dir.EnumerateDirectories()
Dim item As TreeViewPlus = New TreeViewPlus(folder)
item.Name = Text.RegularExpressions.Regex.Replace(folder.FullName, "[^a-zA-Z0-9]", "")
item.Header = folder.Name
Me.Items.Add(item)
Next
Catch ex As Exception
End Try
MyBase.OnExpanded(e)
End Sub
Short Question, is it possible to disable Characters Entry in a DataPicker so that the User is just allowed to enter numbers and dots and slashes?
Kind Regards
You could handle the PreviewTextInput event of the DatePicker something like this:
<DatePicker x:Name="dp" PreviewTextInput="DatePicker_TextChanged" />
Private Sub DatePicker_TextChanged(sender As Object, e As TextCompositionEventArgs)
If Not (Microsoft.VisualBasic.Information.IsNumeric(e.Text) Or e.Text = "." Or e.Text = "/" Or e.Text = "\") Then
e.Handled = True
End If
End Sub
Is there anyway to do this in Code behind?
Sure. Try this:
AddHandler dp.PreviewTextInput, AddressOf DatePicker_TextChanged
You're going to have to do it yourself :
<TextBox PreviewTextInput="TextBox_PreviewTextInput"/>
private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
if(!is_number(e.Text) && !is_dot(e.Text) && ...)
{
e.Handled = true;
}
}
Setting e.Handled = true intercepts the event and prevents the action to take place.
I would recommend using a regex instead of is_number etc... (I'm sure there are plenty of examples of regexes out there).
Note that this will not work with spacebar, you will have to use the previewkeydown event for that, and there might be some other keys that are not treated in PreviewTextInput and that would modify your Text, but I can not think of any.
EDIT :
I just saw you use VB, the code I posted is for C#, I don't know any VB but I imagine it shouldn't be that different.
So my issue may sound familiar, I simply want to update a progress bar concurrently with the data that is being processed in my program.
I have two windows: StartupWindow and UpdateWindow.
The Application begins by creating the startup window, the user will push a button to open the UpdateWindow. The following is the code for the button:
Private Sub btnUpdateClick(sender As Object, e As RoutedEventArgs) Handles btnUpdate.Click
Dim updateWindow As New UpdateWindow
updateWindow.ShowDialog()
btnUpdate.IsEnabled = False
End Sub
With this code I got the error most other people do: "The calling thread cannot access this object because a different thread owns it."
Private Sub updateDevice()
Dim currPercent As Integer
currPercent = ((sentPackets / totalPacketsToWrite) * 100)
progressLabel.content = currPercent.ToString + "%"
pb.Maximum = totalPacketsToWrite
pb.Value = sentPackets
If sentPackets < totalPacketsToWrite Then
'....update....
Else
MsgBox("Device now has update stored on flash!")
'...close everything up
End If
End Sub
Here are the three things I have tried so far:
Use Invoke/Dispatcher/Delegate to try and seem to only be able to put the update in a different thread's queue? Can't seem to pause other the other threads to update the UI either...
Implement the BackgroundWorker Class and use report progress from it, this worked but I could only update the progress bar under bw.DoWork I make a lot of calls and have responses from external devices so it would be difficult to put all my code under one function.
I read somewhere that since this was the second window created (called from the original) I would have issues with it. So I took someone's solution and tried to create and entire new thread when the 'update' button was pressed ie.:
Something to note is that I added a 'cancel' button:
Private Sub buttonStart_Click(sender As Object, e As RoutedEventArgs) Handles btnStart.Click
btnStart.IsEnabled = False
btnStart.Visibility = Windows.Visibility.Hidden
btnCancel.IsEnabled = True
btnCancel.Visibility = Windows.Visibility.Visible
beginUpdate()
End Sub
Private Sub buttonCancel_Click(sender As Object, e As RoutedEventArgs) Handles btnCancel.Click
btnStart.IsEnabled = True
btnStart.Visibility = Windows.Visibility.Visible
btnCancel.IsEnabled = False
btnCancel.Visibility = Windows.Visibility.Hidden
'TODO MAKE IT CANCEL
End Sub
And every time I clicked the update/cancel button the progress bar would update. Every time I pressed the button it refreshed the progress bar to the current completion. I'm quite puzzled, I am able to update user interfaces if it is just one window... but if the user pushes a button to call a new window I cannot update anything in the second window. Any suggestions?
EDIT:
I ended up making global variables that updated in my long code. Than ran backgroundworker before I did anything else and it ran asynchronous to my process, updating the progress bar:
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
While finished = False
Threading.Thread.Sleep(50)
bw.ReportProgress(currPercent)
End While
End Sub
The start of my code was simple - like so:
Private Sub buttonStart_Click(sender As Object, e As RoutedEventArgs) Handles btnStart.Click
bw.RunWorkerAsync()
beginUpdate()
End Sub
First things first... get the ProgressBar working: For this part, please read my answer to the Progress Bar update from Background worker stalling question here on Stack Overflow. Now, let's assume that you've got the basic update of a ProgressBar working... next, you want to be able to cancel the work. It is a simple matter to update the DowWork method accordingly:
private void DoWork(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 100; i++)
{
if (IsCancelled) break; // cancellation check
Thread.Sleep(100); // long running process
backgroundWorker.ReportProgress(i);
}
}
So all you need to do to cancel the long running process and the ProgressBar update is to set the IsCancelled property to true.
I am trying to print from VB2010 Windows Forms using the Microsoft.VisualBasic.Compatibility.VB6 library.
I have downloaded the library and imported it onto my form. The Microsoft help files are inaccurate and incomplete, and there is not a complete example. A simple form with a print button that prints "Hello World!" to the default system printer would be enough to get me started.
Thanking you in advance for any help offered...
Using the proper library will go a long end to making this simple. Use the PrintDocument class instead:
Imports System.Drawing.Printing
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim doc = New PrintDocument()
AddHandler doc.PrintPage, AddressOf PrintHello
doc.Print()
End Sub
Private Sub PrintHello(sender As Object, e As PrintPageEventArgs)
e.Graphics.DrawString("Hello world", Me.Font, Brushes.Black, New PointF(0, 0))
End Sub
End Class
I'm using the below to restore a database in VB.NET.
This works but causes the interface to lockup if the user clicks anything.
Also, I cannot get the progress label to update incrementally, it's blank until the backup is complete then displays 100%
Sub DoRestore()
Dim svr As Server = New Server("Server\SQL2008")
Dim res As Restore = New Restore()
res.Devices.AddDevice("C:\MyDB.bak", DeviceType.File)
res.Database = "MyDB"
res.RelocateFiles.Add(New RelocateFile("MyDB_Data", "C:\MyDB.mdf"))
res.RelocateFiles.Add(New RelocateFile("MyDB_Log", "C:\MyDB.ldf"))
res.PercentCompleteNotification = 1
AddHandler res.PercentComplete, AddressOf ProgressEventHandler
res.SqlRestore(svr)
End Sub
Is this change correct?:
Private Sub ProgressEventHandler(ByVal sender As Object, ByVal e As PercentCompleteEventArgs)
UpdateProgressBar(e.Percent)
End Sub
Private Sub UpdateProgressBar(ByVal e As String)
ProgressBar.Value = e
Status.Text = e.ToString
End Sub
You need to use SqlRestoreAsync not SqlRestore to prevent it tying up your main thread.
Then to avoid the Cross Thread Operation error when updating the UI you can use the approach here. Where you create a method on the form that will update the UI elements and call that from your asynch handler using Invoke.