Manually setting top and left position of startup is not working - vb.net

in the load event, I'm setting left and top position. What's happening is the form shows up in the default position, then goes to the location that I set manually. So it flashes at one position then immediately goes to the manual settings. (hope this makes sense.. let me know if I need to provide more info)
Dim rkCurrentUser As RegistryKey = Registry.CurrentUser
If rkCurrentUser IsNot Nothing Then
Dim rkTest As RegistryKey = rkCurrentUser.OpenSubKey("My Secret Life")
If rkTest IsNot Nothing Then
regKey = Registry.CurrentUser.CreateSubKey("My Secret Life")
Dim myLeft As Integer = 0
myLeft = regKey.GetValue("frmMainLeft", myLeft)
Dim myTop As Integer = 0
myTop = regKey.GetValue("frmMainTop", myTop)
Dim myMinutes As Integer = 0
myMinutes = regKey.GetValue("waitMinutes", myMinutes)
Me.Top = myTop
Me.Left = myLeft
regKey.Close()
rkTest.Close()
rkCurrentUser.Close()
End If
Else
MsgBox("Key doesn't exist")
regKey = Registry.CurrentUser.CreateSubKey("My Secret Life")
regKey.SetValue("waitMinutes", 0)
regKey.SetValue("frmMainLeft", Me.Left)
regKey.SetValue("frmMainTop", Me.Top)
regKey.Close()
End If
rkCurrentUser.Close(
Thanks for any help... plus I know the last character is removed.

Here's some sample code that illustrates the kind of thing I usually do:
Function Display() As DialogResult
Me.Icon = frmMain.Icon 'so we only change icons in one place
'other initialisation stuff goes here
RestoreFormSettings(Me) 'get form position (and size if resizable) from registry (your code)
Return Me.ShowDialog() 'show the form modally, then return dialog result
End Function
You should find that this gets rid of the flicker. I've also included what I do to ensure icon consistency across the app, and how to return a DialogResult which is one way for the calling code to know what you did in the form. To clarify, call this instead of calling frm.ShowDialog directly.

Related

Change Font Style on All Instances of a String in a RichTextBox

I'm working on a VB.NET 4.5 project in VS2013.
I have a richtextbox on a form and when a button is clicked I need to toggle the BOLD setting on all instances of a specific string found in the richtextbox.
I put together some code based on this question.
Private Sub ToggleBold()
rtxtOutputText.SelectionStart = rtxtOutputText.Find("##$%", RichTextBoxFinds.None)
rtxtOutputText.SelectionFont = New Font(rtxtOutputText.Font, FontStyle.Bold)
End Sub
However when the toggle bold button is clicked it only bolds the first instance of the string "##$%".
How can I set all instances of the string to bold? There can also be several of them strung together ("##$%##$%##$%"), so each of those would need to be bolded too.
(I know I mentioned toggling bold, but I'll set up the toggle portion later, right now I'm just trying to get the bold on all instances working right...)
Just add a loop to it and use the RichTextBox.Find(String, Int32, RichTextBoxFinds) overload to specify from where to start looking. Look from the current index + 1 so that it doesn't return the same again.
You also ought to actually select the word as well, so that you're sure the bold applies to the current instance only and not the text around it.
Private Sub ToggleBold()
'Stop the control from redrawing itself while we process it.
rtxtOutputText.SuspendLayout()
Dim LookFor As String = "##$%"
Dim PreviousPosition As Integer = rtxtOutputText.SelectionStart
Dim PreviousSelection As Integer = rtxtOutputText.SelectionLength
Dim SelectionIndex As Integer = -1
Using BoldFont As New Font(rtxtOutputText.Font, FontStyle.Bold)
While True
SelectionIndex = rtxtOutputText.Find(LookFor, SelectionIndex + 1, RichTextBoxFinds.None)
If SelectionIndex < 0 Then Exit While 'No more matches found.
rtxtOutputText.SelectionStart = SelectionIndex
rtxtOutputText.SelectionLength = LookFor.Length
rtxtOutputText.SelectionFont = BoldFont
End While
End Using
'Allow the control to redraw itself again.
rtxtOutputText.ResumeLayout()
'Restore the previous selection.
rtxtOutputText.SelectionStart = PreviousPosition
rtxtOutputText.SelectionLength = PreviousSelection
End Sub
Credit to Plutonix for telling me to dispose the font.

Task is running and cannot be finished

Have strange behaviour in my task which is not finishing. I use this all the time but i suppose its because sub i am passing to it is iteracting with form - changing selection and refreshing some listbox probably therefore its stack there but i am not sure. Lets see the code:
This is the sub i want to be run in task:
Public Sub UnselectExistingConnectionsItems()
Dim SentenceId, SubSubKategorieId, SubSectionId As Integer
SubSectionId = CbSubSections.SelectedValue 'combobox
If WithSubSubkategorie = SubSubKategorieEnum.Without Then
SubSubKategorieId = 0
Else
SubSubKategorieId = CbSubSubKategorie.SelectedValue 'combobox
End If
Unselect:
For i As Integer = 0 To LB_Sentences.SelectedItems.Count - 1
Dim sKey As ListBoxItem
sKey = LB_Sentences.SelectedItems(i)
SentenceId = HtmlDescription.HtmlSentence.GetSentenceIdByName(sKey.Text)
If HtmlDescription.HtmlSubSubSections_Sentences.CheckIfConnectionAlreadyExist(SentenceId, SubSectionId, SubSubKategorieId) Then
sKey.IsSelected = False
LB_Sentences.Refresh()
GoTo Unselect
End If
Next
End Sub
i put it to Task like this:
Dim pic As New FrmCircularProgress(eCircularProgressType.Line)
Dim work As Task = Task.Factory.StartNew(Sub()
'--Run lenghty task UnselectExistingConnectionsItems()
'--Close form once done (on GUI thread)
pic.Invoke(New Action(Sub() pic.StopCircular()))
pic.Invoke(New Action(Sub() pic.Close()))
End Sub)
'--Show the form
pic.ShowDialog()
Task.WaitAll(work)
and FrmCircularProgress is just form ( i use it almost everywhere where i have to user wait and its working besides this particural case):
Public Class FrmCircularProgress
Sub New(progressType As DevComponents.DotNetBar.eCircularProgressType)
InitializeComponent()
CircularProgress1.ProgressBarType = progressType
StartCircular()
End Sub
Public Sub StartCircular()
Me.CircularProgress1.IsRunning = True
End Sub
Public Sub StopCircular()
Me.CircularProgress1.IsRunning = False
End Sub
End Class
what could be wrong? is it because procedure is interacting with listbox and combobxes? If so how to fix that, i read something about invoking listbox and comboboxes but have no idea how to fix that.
EDIT:
I think besides those lines:
sKey.IsSelected = False
LB_Sentences.Refresh()
I have to make those:
LB_Sentences.Invoke(Sub() sKey.IsSelected = False
End Sub)
LB_Sentences.Invoke(Sub() LB_Sentences.Refresh()
End Sub)
because i am in diffrent thread. Somehow i dont know how to convert those lines:
SubSectionId = CbSubSections.SelectedValue
SubSubKategorieId = CbSubSubKategorie.SelectedValue
probably loop also have to be invoked. Waiting your help.
There is a rule that says "The only thread that can modify a control in a window is the thread that created the window". Any other thread trying to modify something in the window will generate a cross-thread call exception.
So in your first edit you got it right, you have to invoke the functions.
However, this doesn't fix your problem of not finishing Task.
I believe that doing sKey.IsSelected = False does not unselect anything in your ListBox, therefore causing an infinite loop... Also that Goto statement is very bad programming habits and should not be used. There is always another solution that will make your code easier to debug/maintain/read...
ListBoxItem is not a type that exists in the .Net Framework. So either you created that class either it's something else (and I don't know what...)
What you can do to solve your problem is :
Get the indices of all selected items in a list
Run through your list, and check if they should be selected :
If they should be selected, do nothing
if they shouldn't, unselect them.
Which makes your code like this (and you remove that ugly Label and Goto that you don't want in your code)...
Public Sub UnselectExistingConnectionsItems()
Dim SentenceId, SubSubKategorieId, SubSectionId As Integer
SubSectionId = CbSubSections.SelectedValue 'combobox
If WithSubSubkategorie = SubSubKategorieEnum.Without Then
SubSubKategorieId = 0
Else
SubSubKategorieId = CbSubSubKategorie.SelectedValue 'combobox
End If
'We create an array to remind our initial selection
Dim sel = New Integer(LB_Sentences.SelectedItems.Count - 1) {}
LB_Sentences.SelectedIndices.CopyTo(sel, 0)
For i = 0 To sel.Length - 1
Dim sKey As ListBoxItem
'We get our selected item
sKey = LB_Sentences(sel(i))
SentenceId = HtmlDescription.HtmlSentence.GetSentenceIdByName(sKey.Text)
If HtmlDescription.HtmlSubSubSections_Sentences.CheckIfConnectionAlreadyExist(SentenceId, SubSectionId, SubSubKategorieId) Then
'We must remove it from the selection
LB_Sentences.Invoke(Sub() LB_Sentences.SelectedItems.Remove(sKey))
End If
Next
'We do the Refresh at the end so we gain some process time...
LB_Sentences.Invoke(Sub() LB_Sentences.Refresh())
End Sub

Passing Parameter to Crystal Reports XI from Visual Studio 2015

I am running into problems with the passing of parameters to an externally created Crystal Reports XI report from the WinForms application I'm building in Visual Studio 2015 Community Edition. No matter what I try to do, the report doesn't seem to get the value unless I manually select it at the prompt (which shouldn't even be popping up) when the report is being displayed. I'm using the same code I've used in a previous application (although that one was built in VS2008), but I've tried a number of "alternate" versions of the code in my attempts to get this working. Here's the code that I'm currently using:
Imports CrystalDecisions.CrystalReports.Engine
Imports CrystalDecisions.Shared
Module modReports
Private WithEvents DocumentToPrint As New Printing.PrintDocument
Private Sub ShowReport(ByVal LID As Integer, ByVal InHouse As Boolean)
Dim Report As New ReportDocument
Dim ReportParameters As ParameterFieldDefinitions = Nothing
Dim Parameter As ParameterFieldDefinition = Nothing
Dim ApplicationValue As ParameterDiscreteValue = Nothing
Dim ReportValues As ParameterValues = Nothing
Dim ReportViewer As New frmReport
Dim Response As DialogResult = DialogResult.Cancel
PrintingReport = True
Report.Load(CRYSTAL_REPORT_FILE_PATH & "ExampleReport.rpt")
Report.Refresh()
Report.VerifyDatabase()
ReportParameters = Report.DataDefinition.ParameterFields
Parameter = ReportParameters.Item("PrintAll")
ReportValues = New ParameterValues
ApplicationValue = New ParameterDiscreteValue
'Parameter.CurrentValues.Clear()
'ReportValues.Clear()
ReportValues = Parameter.CurrentValues
If LID = 7777 Then
ApplicationValue.Value = True
Else
ApplicationValue.Value = False
End If
ReportValues.Add(ApplicationValue)
Parameter.ApplyCurrentValues(ReportValues)
Response = MessageBox.Show("Do you want to send this report directly to the printer?", "SEND TO PRINTER", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)
If Response = DialogResult.No Then
With ReportViewer
.rptViewer.ReportSource = Nothing
.rptViewer.ReportSource = Report
.WindowState = FormWindowState.Maximized
.rptViewer.RefreshReport()
' Set zoom level: 1 = Page Width, 2 = Whole Page, 25-100 = zoom %
.rptViewer.Zoom(1)
.rptViewer.Show()
.ShowDialog()
End With
ElseIf Response = DialogResult.Yes Then
Dim SelectPrinter As New PrintDialog
Dim PrinterSelected As DialogResult = DialogResult.Cancel
With SelectPrinter
.Document = DocumentToPrint
.AllowPrintToFile = False
.AllowSelection = False
.AllowCurrentPage = False
.AllowSomePages = False
.PrintToFile = False
End With
PrinterSelected = SelectPrinter.ShowDialog
If PrinterSelected = DialogResult.OK Then
Dim Copies As Integer = DocumentToPrint.PrinterSettings.Copies
Dim PrinterName As String = DocumentToPrint.PrinterSettings.PrinterName
Dim LastPageNumber As Integer = 1
Dim PrintBuffer As String = String.Empty
LastPageNumber = Report.FormatEngine.GetLastPageNumber(New ReportPageRequestContext)
Report.PrintOptions.PrinterName = PrinterName
Report.PrintOptions.PrinterDuplex = DocumentToPrint.PrinterSettings.Duplex
Report.PrintToPrinter(Copies, True, 1, LastPageNumber)
If Copies = 1 Then
PrintBuffer = "Printed " & Copies & " copy of "
Else
PrintBuffer = "Printed " & Copies & " copies of "
End If
If LastPageNumber = 1 Then
PrintBuffer += LastPageNumber.ToString & " page."
Else
PrintBuffer += LastPageNumber.ToString & " pages."
End If
MessageBox.Show("The report was sent to the following printer:" & vbCrLf & " • " & PrinterName & vbCrLf & PrintBuffer, "REPORT PRINTED", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End If
PrintingReport = False
End Sub
End Module
The report itself is built to use an XML file as the data source, which is dynamically created by this application. All of that works normally, and oddly enough, if I send the report directly to the printer, it seems to print correctly without prompting me. It's only a problem when I try to display the report through the CrystalReportViewer object.
Some of the things I've tried without success:
I've tried with and without calling the Clear() methods on the
Parameter.CurrentValues and ReportValues objects.
I've tried moving all of the parameter setting logic to after I set the
ReportSource of the CrystalReportViewer control (rptViewer.ReportSource)
I've tried using alternate Crystal Reports objects (ParameterFields instead of ParameterFieldDefinitions and ParameterField instead of ParameterFieldDefinition).
I've tried removing all of the "complicated" code and just using the SetParameterValue method (i.e., Report.SetParameterValue("PrintAll", True)
I've even tried creating different types of parameter fields in the report itself (String, Boolean, Number) and passing appropriate values for those datatypes.
If I walk through the code, it doesn't appear to error out anywhere, and everything looks like it's working just great until I get to the .rptViewer.RefreshReport() line in the With ReportViewer block. I've verified that all of the parameters and values have only the value I am "selecting" via the application by checking them every step up to that point, and it all looks exactly as I expect it to look.
But the application (via Crystal Reports) continues to prompt me for the value I just passed in the code. If I select the value in that prompt, the report does generate correctly based on the value I select, but no matter what I "pass" in the programming, the prompt always defaults to True.
Does anyone have any suggestions that I may have overlooked for how to get this parameter to correctly pass to the CrystalReportViewer control? Please let me know if you need any additional information or have any questions about what I've set up so far here. Thank you in advance.
Okay, so based on the information I found over on http://www.it-sideways.com/2011/10/how-to-disable-parameter-prompt-for.html, it seems that the RefreshReport method for the CrystalReportViewer control basically wipes out any parameters and/or log on information:
1. ) Do not invoke CrystalReportViewer.RefreshReport Method
This method will refresh the data for the report currently displayed
in the CrystalReportViewer control. The report will prompt for
parameters or logon info is necessary.
So, this method is not needed unless the same
CrystalDecisions.CrystalReports.Engine.ReportDocument object is
reused.
By commenting out that line of the code, I was able to prevent the parameter prompt from being displayed. The only issue I have after making that change is that, even though the zoom level is being set to 1 (page width), and when I run the project the CrystalReportViewer control even shows that it's correctly set in the status bar ('Zoom Factor: Page Width' is displayed), the report itself is not actually zoomed in to the page width.
With the RefreshReport method uncommented, if I manually provided the value for my parameter, it would display the report properly zoomed. If I add the zoom button to the control (.rptViewer.ShowZoomButton = True), I can manually choose the Page Width option, which then correctly "re-zooms" the report to the desired level, but it won't immediately display that way if the RefreshReport method is not called.
Regardless, I can spend some time trying to fight that now, but I finally have it properly setting, passing and displaying the results of my parameter. I hope this helps someone else running into this issue.

Picturebox location change 20 times per second not redrawing

I'm trying to make a few images do the nice slidey thingy that I've seen lots of Microsoft applications use. The one where the movement starts slow speeds up half way there and then comes to a nice slow stop in it's new location. I've got all the calculations figured out, getting and setting the picture box locations, Confirmation using console.writeline that the image locations are correct, and even a test run that works in a simplified format.
But in the full blown version It's not repainting the image. In fact, it looks like nothing has happened at all while the script is running. I've tried Me.Refresh(), Invalidate(), Timer.Enabled = True/False, and Me.Update(). None of which have worked. The last step is the most frustrating: I'm calling my SetPanelLocation() method at the end to ensure that the panel ends up in the final location regardless of if the movement worked. Nothing happens on this call either, even though immediately after this routine fails I can call the same method from another user event and it starts working again like nothing was wrong.
I'm creating my own PictureBox class called clsFeedImageBox which inherits PictureBox that includes this functionality (along with other features). Each image is only 300x225 pixels so they're not massive images that take a lot of time to redraw. Each instance of this class is in a common Forms.SplitterPanel. I use a lot of comments out of habit so i left them in here, maybe they'll add some light.
Public Class clsFeedImgBox
Inherits PictureBox
Private iRank As Integer 'rank in whatever feed this file gets put in
Private iRankTarget As Integer 'rank to move to when rank feed event starts
Private iTopStart As Integer 'starting top location before feed event
Private iTopTarget As Integer 'final Top location after feed event
Private WithEvents tMyTimer As New System.Timers.Timer
Private WithEvents oParent As FeedBase 'splitter panel, all location info comes from the parent
Public Sub New(ByRef sender As FeedBase, ByVal rank as Integer)
'set objects
oParent = sender
'set .Image property to pre-made thumbnail
Image.FromFile(ThumbPath) 'ThumbPath is a property which is set by this point (some code has been removed)
'setup initial position
setPanelLocation(rank)
'set autosize
Me.SizeMode = PictureBoxSizeMode.StretchImage
'set Image Scroll timer interval to 20 fps (1000 / 20 = 50)
tMyTimer.Interval = 50
End Sub
Public Sub scroll(ByVal newRank As Integer)
'setPanelLocation(newRank) <== this works, timed movements don't
iRankTarget = newRank
iTopStart = Me.Top
iTopTarget = oParent.ImgTop(newRank) 'gets an integer for the new Top location
tMyTimer.Start()
End Sub
Private Sub myScrollStep() Handles tMyTimer.Elapsed
'tMyTimer.Enabled = False 'this idea with the enabled = True at the end didn't work
iTickCount += 1
Dim iScrollPerc As Integer 'scroll % between Start and End * 100
iScrollPerc = oParent.ScrollStep(iTickCount, Rank) 'this part works
Console.WriteLine(strThumbName & " scrollPerc: " & iScrollPerc.ToString)
If iScrollPerc >= 100 Then
'scroll event complete
Console.WriteLine(strThumbName & " SetFinalLocation")
Me.setPanelLocation(iRankTarget) '<== This line doesn't work here, but works when called by other means
'stop Feed updates
tMyTimer.Stop()
'reset iTickCount for next movement
iTickCount = 0
Else
'scrolling still going
Dim newTop As Integer
newTop = Math.Round(iTopTarget - (((100 - iScrollPerc) * (iTopTarget - iTopStart)) / 100)) 'this part works
'Console.WriteLine(strThumbName & " TopTarget: " & newTop)
Me.Top = newTop 'Nothing happens here
End If
'Me.Left = oParent.ImgLeft
'Me.Width = oParent.ImgWidth
'Me.Height = oParent.ImgHeight 'that didn't work
'Me.Refresh() 'this didn't work
'Invalidate() 'this didn't do much good either
'Me.Update() 'Aaaaand no cigar, time for StackOverflow
'tMyTimer.Enabled = True
End Sub
Public Sub setPanelLocation(ByVal rank As Integer)
iRank = rank
Me.MyRePaint()
End Sub
Public Sub MyRePaint()
'repaint image box with everything in it's current rank
Me.Left = oParent.ImgLeft
Me.Top = oParent.ImgTop(iRank)
Me.Width = oParent.ImgWidth
Me.Height = oParent.ImgHeight
End Sub
End Class
What gives? There must be some inner workings of VB.NET that will help me figure this out. I'm using VS 2012 and Win8
You could make a WPF application and use a Slider control instead of "manually" making a slider with planes, picture boxes, etc, etc.

Adding Progress bar while loading Image list to listbox using vb.net

I am trying to add Images using open file dialog and folder browse dialog and populating the image list to listbox.While adding these Images I need to show the progress bar for every image it loads.
I am trying to get that but when the value of the progress bar say something around 25 0r 40 it is stopping at that point but I need to show the progress bar until it completes the 100% and then populates the Image list.
How do I do that?
Here is my code:
Private Sub AddImages_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddImages.Click
If Not Directory.Exists(Application.StartupPath + "\Backup\") = True Then
Directory.CreateDirectory(Application.StartupPath + "\Backup\")
End If
OpenFileDialog1.FileName = "Select a Image"
OpenFileDialog1.Multiselect = True
OpenFileDialog1.InitialDirectory = "C:\Users\Public\Pictures\Sample Pictures"
OpenFileDialog1.Filter = "All Type Of Image Files|*.*|Joint Photographic Experts Group [JPEG]|*.jpg|Bitmap [BMP|*.bmp|Tagged Image File Format [TIFF]|*.tiff|Portable Network Graphics [PNG]|*.png"
If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
ProgressBar2.Show()
ProgressBar2.Step = 10
Dim str As String
For Each str In OpenFileDialog1.FileNames
Load.Text = "Loading..."
Dim fso As New FileSystemObject
Dim MyName As String
Dim MyExtension As String
MyName = fso.GetFileName(CStr(str))
MyExtension = fso.GetExtensionName(MyName)
System.IO.File.Copy(str, Application.StartupPath + "\Backup\" + MyName & "." & MyExtension, True)
CheckedListBox1.Items.Add(str, CheckState.Checked)
Thumbcontrol1.AddThumbnail(str)
Thumbcontrol1.BackgroundImage = Nothing
CheckedListBox1.SelectedIndex = 0
ProgressBar2.PerformStep()
Next
SaveProject.Enabled = True
Delete.Enabled = True
Edit.Enabled = True
ClearAll.Enabled = True
CheckAll.Enabled = True
UncheckAll.Enabled = True
Timer1.Stop()
Load.Text = "Loading Completed"
Else
End If
ProgressBar2.Visible = False
Load.Text = Nothing
End Sub
Remove ProgressBar2.Step = 10 line and do this:
Dim str As String
Dim counter As Integer 'new!
For Each str In OpenFileDialog1.FileNames
Load.Text = "Loading..."
Dim fso As New FileSystemObject
Dim MyName As String
Dim MyExtension As String
MyName = fso.GetFileName(CStr(str))
MyExtension = fso.GetExtensionName(MyName)
System.IO.File.Copy(str, Application.StartupPath + "\Backup\" + MyName & "." & MyExtension, True)
CheckedListBox1.Items.Add(str, CheckState.Checked)
Thumbcontrol1.AddThumbnail(str)
Thumbcontrol1.BackgroundImage = Nothing
counter += 1 'new
CheckedListBox1.SelectedIndex = 0
ProgressBar2.Value = (counter * 100) / OpenFileDialog1.FileNames.Length 'new
Next
It does not address the problem of your not using threading, as other answers are correct to point out.
Don´t use the UI for loading. Use Background worker. BackgroundWorker works in another thread, and it can report the progress to bind it to a progressbar.
The progress bar stops moving because Windows thinks there is something seriously wrong with your program. It replaces your main window with the 'ghost' window, you can tell because it says "Not Responding" in the title bar.
It does this to help alert the user that your program is dead to the world and will not respond to any input from the user. Clicking the mouse or banging on the keyboard will not have any effect, all the user can do is watch helplessly while your code goes through the motions.
This does not make a desirable user interface. You solve it by using BackgroundWorker so the heavy lifting is done on a separate thread. Leaving the user interface thread responsive. Be sure to read the MSDN article for it so you know what to do, you'll have to adapt your code.