Persist user form size and location settings per session
My prior post (Create your own Test Host using XAML to run your unit tests) shows how to create a form and present it to the user. The user can resize and reposition the form, even on a 2nd monitor.
When the user exits the form, we can persist or remember the form size and location, so the next time the user form starts up, it will be positioned/sized as before.
The happens to be a XAML form, but it could be a WinForm for this to work. (The My.Settings feature has been in Visual Studio for many years…)
Because FoxPro has its own database engine, Fox can persist data in a Fox table. The positions and sizes of design time windows, such as the Command Window, Project Window, Database Windows, are persisted in the FoxPro Resource file. The FoxResource class (unzip the xsource.zip file in tools\xsource and look in the EnvMgr folder) can help users persist user forms there too.
To add this feature to your VB project:
Go to Project->Properties->Settings, and add 2 settings:
- Location, type=System.Drawing.Point, default = 0,0
- Size, type=System.Drawing.Size, default=1024,768
In the Load or New method:
If System.Windows.Forms.Screen.AllScreens.Count = 1 AndAlso _
My.Settings.Location.X > System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width Then
Me.Left = 0 ' if the saved .X is out of range (multimonitor, remote desktop)
Me.Left = My.Settings.Location.X
Me.Top = My.Settings.Location.Y
Me.Width = My.Settings.Size.Width
Me.Height = My.Settings.Size.Height
AddHandler Me.Closed, AddressOf OnWindowClosed
Sub OnWindowClosed(ByVal sender As Object, ByVal e As EventArgs)
My.Settings.Location = New System.Drawing.Point(CInt(Me.Left), CInt(Me.Top))
My.Settings.Size = New System.Drawing.Size(CInt(Me.Width), CInt(Me.Height))
The data is stored in an XML file like:
"C:\Documents and Settings\Calvinh\Local Settings\Application Data\Microsoft\<appname>\126.96.36.199\user.config”
which looks like:
<?xml version="1.0" encoding="utf-8"?>
<setting name="Location" serializeAs="String">
<setting name="Size" serializeAs="String">
If you’re feeling brave, you can persist multiple strings using System.Collections.Specialized.StringCollection.
I store things like which items are selected and how many asserts are fired per test. Each string will have 3 comma separated items: TestClass,TestName, and AssertCnt
For Each itm In m_TestMethods
Dim theitem = itm
Dim res = From a In My.Settings.AssertsPerTest _
Let strs = CStr(a).Split(","c) _
Where strs(0) = theitem.TestClass And strs(1) = theitem.TestName _
Let Assertcnt = CInt(strs(2))
If res.Count > 0 Then
itm.AssertCnt = res.First.Assertcnt
And just before My.Settings.Save is called, we’ll create the string collection to save.
Dim ColAssertsPerTest = New Specialized.StringCollection
For Each itm In From d In TestMethods Where d.AssertCnt > 0
ColAssertsPerTest.Add(itm.TestClass + "," + itm.TestName + "," + itm.AssertCnt.ToString)
My.Settings.AssertsPerTest = ColAssertsPerTest
Notice the use of Linq in the For Each expressions.
I also use Linq to find the total # of asserts fired:
Dim nTotalAssertsExpected = Aggregate itm In m_SelectedTests Into Sum(itm.AssertCnt)
See also: another example of persisting settings: The VB version of the Blog Crawler