 |
|
 |
If you add a suspend and resume layout at the appropriate points, the controls won't flicker when you switch between categories.
Private Sub tvCategories_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles tvCategories.AfterSelect
SuspendLayout() For i As Integer = 0 To UBound(sets) ... ... Next tlp.ResumeLayout() 'Update the TabIndex of controls already on the form
===============================================================
ClearOptions() tlp.SuspendLayout() While tlp.Controls.Count > 0 ... ... End While tlp.ResumeLayout()
Neat control and thanks!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I am loving your control by the way, but I have a requirement that I am trying to come up with a solution for and am looking for some comments from either you or other readers here.
My application needs to set several paths (temp folder, etc...) and I am not seeing any easy way to get the UI of this system to render a browse button next to a text box if I am looking for path input. I would like to be able to present the user with a browse button (...) to open up a folder browser dialog box so they can pick the folder (or create a new one on the fly) and have that setting placed into the text box.
Any ideas?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I'm glad you like it.
I had worked out with someone at one point a version of this that would do just what you are saying.
It will take some time to dig up, but once I find it I'll email it to you.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hey U need the code or technic of how to use the folder browsing option? reply to anand.krishk@hotmail.com
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi, i need to create project in vb.net 2005, i have a file named textsort.text containing lines like this Line1 "478275605 000001200000000199908169000000000000072DIWO" Line2 "108710641 0001300001993011995101212160000000014758GDQ01" Line3 "114305469 0001300001999011999070815120000000028313BDQ01" ... , i want to sort by Exemple: Start Position 52(could be 44 or 10 or ...), Number of Char 4,descending or ascending and save file in different name. Thank you all.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
I'm not following how I can add this to my project. I tried to copy Form1.vb and the resx and designer.vb to my project folder. Then from the solution explorer I right clicked my soution name and selected Add -> Existig Item and selected the form. I then get 4 errors about "SettingsDialog.FireFoxPane" and "SettingsDialog.FireFoxBar" not being defined. The error is in refrence to the designer.vb. Can someone help a newbie out?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Yes...
I've noticed that as a slight problem.
I've added thoses classes - FireFoxPane, FireFoxBar, and FireFoxItem in Form1.vb.
The four errors are the four instances of those being declared. Twice for each Pane/Bar (declaration and instantiation).
Try changing the declaration of them. SettingsDialog was the name of the project I used to create it. Try changing SettingsDialog.FireFoxPane to FireFoxPane.
If that doesn't take care of it let me know - I've got some other ideas if that is not the case.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Yep, removing the "SettingsDialog." from those four lines in the .designer.vb did the trick. I'm not clear on why, but thank you very much. I did rename the Form1.* files to SettingsDialog.*. would that do it? If I named it something else would it have been fine?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Well, after getting it to work, it occured to me that half of the settings for my program deal with the locations of files or directories on the local computer. These values really are just strings, the but controls on the settings form would really need to be able to allow a user to click a Browse button to pick the file. As it stands, they'd have to type/paste in the path and hope they did it right since there is no sanity checking. Any suggestions on how to work around this?
I wanted to write a custom control that was a text box with a button, and if the file didn't exist, the back ground color of the text box would be a different color. Does such a thing exist? Could it work with this Settings Dialog?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Such a thing does not exist natively, no, but it could be built.
In fact you could also embed a FileDialogBox within the custom control, and have that popup too.
The difficulty is in tieing it to an Application setting, as string is already associated with a textbox.
Once I figure that one out - I'm going to include that here as well.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I'm not versed in making a custom control, so I wanted to investigate that. Any tips you can offer me would be great ;] I already wrote the code for text boxes on a windows app I already wrote, but making it an item in the VisualStudio Toolbox and all that...I'm not sure where to start.
As for making SettingsDialog know to draw this custom control, I figure you could make it part of the setting's name. Maybe something like Group_File_Name__of__Setting_0 or Group_Dir_Name__of__Setting_1 but that requires some more changes to properly parse it name when you split on _'s.
On a side note, I sort of hacked a way to have a 'hidden' Setting. I made it so that when the Setting name ended with an _ it doesn't draw. In the Form1_Load sub, where you check "If sp.Name.IndexOf("_") <> -1 AndAlso IsUserScope(sp) AndAlso IsAllowedType(sp) Then" I also check the last character of sp.Name to make sure its not an underscore.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Just as an FYI, I've been working on that custom control. I've called it "FileFolderTextBox" and I've got it working for Files. It's still pretty rough, but I'll let you know when I've got it further along.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Great - actually I've been working on it too. I've got two controls, one for files, and one for folders. Basic functionality is in them and I got the settings dialog to recognize user types in the setting name.
Ex. Misc___File___Background__Image_0 (Misc group, type File, name Background Image)
The only way I could figure was to just add another underscore - the user type must be surrounded by triple underscores, and not be the last thing in the name.
I've got the code all working, now I just have to get the article updated.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I ended up making custom control out of a textbox that checks for Files or Folders, then built two user controls, one for Files and one for Folder which have the FileFolderTextBox, but also have a button that lets you select the file or folder. Sounds good tho, I'm anxious to see it. Maybe we can swap notes.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
HI, this code it's really usefull.
But I don't find the firefox panel and bar in the zip file. They are missing? Where I can get them?
THanks for your help.
Best Regards Massimo
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
HI, sorry I got it work.
VS 2005 give me this message:
Could not find type 'SettingsDialog.FireFoxBar'. Please make sure that the assembly that contains this type is referenced. If this type is a part of your development project, make sure that the project has been successfully built.
But it works anywy.
Thanks Massimo
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Hello, is there a translation to c# available? I think there are a few more difference than just to translate the code. Setting values are not autoatically saved or put to controls and so on.
Thanks for your help
Thomas
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
you can convert VB to C# with some software, but those software need you change one VB project's setting
In project setting: complie page: configuring: Option strict
change it from "Off" to "ON" ..............................
This need VB program writed in explit "type" mode.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi, thank you for the great example. I want use it for the configuration of SerialPort, so I added the support of enum types.
There was an problem by calling "frmOptions.Showdialog" more than once: Entries from last calls are not delete. So I cleared Settings and the tabPages bevore adding new.
Here is the modified code from frmOptions.vb
Public Class frmOptions Private Settings As New SettingInfoCollection Private _bUseTabPages As Boolean = True
''' <summary> ''' Determines whether the dialog box will use TabPages or a TreeView to display the categories. ''' </summary> ''' <value>Boolean: True - Use TabPages; False - Use TreeView</value> ''' <returns>Boolean: True - Use TabPages; False - Use TreeView</returns> Public Property UseTabPages() As Boolean Get Return _bUseTabPages End Get Set(ByVal value As Boolean) _bUseTabPages = value End Set End Property
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load '##### remove old entries from last calls Settings.Clear() 'Load the SaveOnExit value chkSaveOnExit.Checked = My.Application.SaveMySettingsOnExit 'Setup the Setting property object for grabing all the settings Dim sp As System.Configuration.SettingsProperty = Nothing
'Cycle through each setting and add it if appropriate. For Each sp In My.Settings.Properties 'If the name doesn't have an underscore - we can't assign a category so we can't change it. 'If the setting is ApplicationScoped - we aren't able to change it at runtime. 'Check also if there is support on this form for the System.Type the setting is. If sp.Name.IndexOf("_") <> -1 AndAlso IsUserScope(sp) AndAlso IsAllowedType(sp) Then 'Passed the tests create a new SettingInfo object Dim newSetting As New SettingInfo 'Load the settings data into the object newSetting.LoadData(sp.Name) 'Add the object to the collection Settings.Add(newSetting) End If Next
'Sort the settings by category - makes the TreeView look nice quickSort(Settings) 'If we're using tabpages hide the TreeView and main TableLayoutPanel If _bUseTabPages Then 'Hide the TreeView mode settings controls tvCategories.Visible = False tlp.Visible = False 'Show the TabControl tcMain.Visible = True tcMain.TabIndex = 0 'Load the settings into the TabControl LoadTabControl() Else 'Hide the TabControl tcMain.Visible = False tvCategories.Visible = True tvCategories.TabIndex = 0 tlp.Visible = True 'Load the settings into the TreeView LoadTreeView() End If End Sub
#Region " Sorting Functions "
''' <summary> ''' Bootstrap starts the quick sort method of sorting a SettingInfoCollection. Sorts alphabetically by category. ''' </summary> ''' <param name="col">The SettingInfoCollection you wish to sort.</param> Private Sub quickSort(ByRef col As SettingInfoCollection) 'Call the actual sorting method SortIt(col, 0, col.Count - 1) End Sub ''' <summary> ''' QuickSort subroutine that does the sorting for a SettingInfoCollection. ''' </summary> ''' <param name="SortArray">The SettingInfoCollection to sort.</param> ''' <param name="First">The starting element of the selection you wish to sort (usually 0).</param> ''' <param name="Last">Then final element of the selection you wish to sort (usually the Count - 1 of the collection).</param> ''' <remarks>Called by the quickSort subroutine</remarks> Private Sub SortIt(ByRef SortArray As SettingInfoCollection, ByVal First As Long, ByVal Last As Long) 'Copied and modified code to support sorting of the SettingInfoCollection 'using strings Dim Low As Long, High As Long Dim Temp As SettingInfo = Nothing Dim List_Separator As SettingInfo = Nothing Low = First High = Last List_Separator = SortArray((First + Last) / 2).Clone Do Do While (SortArray(Low).Category < List_Separator.Category) Low += 1 Loop Do While (SortArray(High).Category > List_Separator.Category) High -= 1 Loop If (Low <= High) Then Temp = SortArray(Low).Clone SortArray.SetItem(Low, SortArray(High)) SortArray.SetItem(High, Temp) Low += 1 High -= 1 End If Loop While (Low <= High) If (First < High) Then SortIt(SortArray, First, High) If (Low < Last) Then SortIt(SortArray, Low, Last) End Sub
#End Region
#Region " Loading Functions " ''' <summary> ''' Checks whether the dialog supports a given type for editing. ''' </summary> ''' <param name="se">A SettingsProperty object as found in the My namespace.</param> ''' <returns>Boolean: True editing is supported, false editing is not supported.</returns> Private Function IsAllowedType(ByVal se As System.Configuration.SettingsProperty) As Boolean 'Build an array of allowed System.Types that this form supports.
Dim allowTypes() As Type = {GetType(Boolean), GetType(Byte), GetType(Char), GetType(Date), _ GetType(Decimal), GetType(Double), GetType(Integer), GetType(Long), _ GetType(SByte), GetType(Short), GetType(Single), GetType(String), _ GetType(Color), GetType(Font), _ GetType(UInteger), GetType(ULong), GetType(UShort)}
'If the type of the property is found in the array - the type is supported. If Array.IndexOf(allowTypes, se.PropertyType) <> -1 Then Return True '##### enum type If (se.PropertyType.BaseType.Name = "Enum") Then Return True 'The type must not be supported if it got here Return False End Function ''' <summary> ''' Checks whether the Setting is writable or not. ''' </summary> ''' <param name="sp">A SettingsProperty as specified in the My namespace.</param> ''' <returns>Boolean: True setting is writable, false setting is read-only.</returns> Private Function IsUserScope(ByVal sp As System.Configuration.SettingsProperty) As Boolean 'The scope of the setting is stored in the Attributes of the setting 'we must cycle through all settings and search for an ApplicationScopedSettingAttribute 'or a UserScopedSettingAttribute For Each o As Object In sp.Attributes.Values 'If we find an ApplicationScopedSettingAttribute the setting isn't UserScoped so return false If TypeOf (o) Is System.Configuration.ApplicationScopedSettingAttribute Then Return False 'If we find a UserScopedSettingAttribute then the setting is UserScoped so return true If TypeOf (o) Is System.Configuration.UserScopedSettingAttribute Then Return True Next 'If we didn't find either of them, it isn't UserScoped (and I'm not sure what it is) so return false Return False End Function
''' <summary> ''' Cycles through eact setting and makes sure the category is in the TreeView ''' </summary> ''' <remarks></remarks> Private Sub LoadTreeView() 'If there are no settings - do not try loading the treeview If Settings.Count = 0 Then Exit Sub 'Cycle through all of the loaded settings For Each si As SettingInfo In Settings 'Add the categories to the root of the TreeView AddCat(tvCategories.Nodes, si.Category.Split("."), 0) Next End Sub ''' <summary> ''' Adds categories/sub-categories to a TreeView. ''' </summary> ''' <param name="parent_nodes">The TreeNodeCollection to which you wish to add the category/sub-category</param> ''' <param name="fields">An array of categories/sub-categories. Index 0 is the Category everything else is a sub-category of the index before it.</param> ''' <param name="field_num">The index with which to the current TreeNodeCollection level. For a TreeNode.Nodes object this would most likely be 0.</param> Private Sub AddCat(ByVal parent_nodes As TreeNodeCollection, ByVal fields() As String, ByVal field_num As Integer) 'If there were no fields passed - we can't add anything to the TreeView so exit the sub 'Also exit if we reached then end of the field list If field_num > fields.GetUpperBound(0) Then Exit Sub
Dim found_field As Boolean 'Check each node of the parent to see if it category/sub-category already exists For Each child_node As TreeNode In parent_nodes If child_node.Text = fields(field_num) Then 'It exists so check this node for the next sub-category AddCat(child_node.Nodes, fields, field_num + 1) found_field = True End If Next child_node
'If we didn't find the node - then add it If Not found_field Then Dim new_node As TreeNode = parent_nodes.Add(fields(field_num)) 'Check the next sub-category in the field list AddCat(new_node.Nodes, fields, field_num + 1) End If End Sub
''' <summary> ''' Cycles through all the Main categories, creating a TabPage and loading the control into it. ''' </summary> Private Sub LoadTabControl() Dim cat As SettingCategoryCollection = Settings.GetCategories '##### : remove Tabpages from last calls tcMain.TabPages.Clear() For Each str As SettingCategory In cat Dim tp As New TabPage tp.Text = str.MainCat tp.Tag = str.SubCats tp.UseVisualStyleBackColor = True LoadTabPageContents(tp.Text, tp) tcMain.TabPages.Add(tp) Next End Sub ''' <summary> ''' Loads the settings editing controls into a TabPage. ''' </summary> ''' <param name="cat">The Main category of the controls you wish to add.</param> ''' <param name="tp">A reference to the TabPage you wish to add the controls to.</param> Private Sub LoadTabPageContents(ByVal cat As String, ByRef tp As TabPage) 'Create a new TableLayoutPanel to layout the controls for the settings Dim ntlp As New TableLayoutPanel ntlp.Name = cat ntlp.Dock = DockStyle.Fill ntlp.ColumnCount = 2 ntlp.ColumnStyles.Add(New ColumnStyle(SizeType.AutoSize)) ntlp.ColumnStyles.Add(New ColumnStyle(SizeType.AutoSize)) ntlp.AutoSizeMode = Windows.Forms.AutoSizeMode.GrowAndShrink ntlp.AutoScroll = True 'Add the new TableLayoutPanel to the TabPage tp.Controls.Add(ntlp) 'Reset the TabIndex for the dynamic controls Dim tbIdx As Integer = 1 'Get all the settings for this TabPage Dim sets() As SettingInfo = Settings.GetByTabCategory(cat) 'If there aren't any we must exit If sets Is Nothing Then Exit Sub 'Some declaration to make things easier in the loop Dim lbl As Label = Nothing Dim dc1 As DockStyle = DockStyle.Fill Dim dc2 As DockStyle = DockStyle.None Dim x As RowStyle 'Cycle through this category's settings For i As Integer = 0 To UBound(sets) lbl = New Label x = New RowStyle x.SizeType = SizeType.AutoSize lbl.AutoSize = True 'If we've reached the end of the settings - don't use the Fill DockStyle If i = UBound(sets) Then lbl.Dock = dc2 Else lbl.Dock = dc1 lbl.TextAlign = ContentAlignment.MiddleLeft If TypeOf (sets(i).Value) Is Boolean Then 'If the setting is a boolean use a checkbox for editing 'Setup the label lbl.Text = sets(i).Name 'Add the label ntlp.Controls.Add(lbl) ntlp.RowStyles.Add(x) 'Setup the checkbox Dim chk As New CheckBox chk.Name = sets(i).TrueName chk.Tag = GetTypeAbbr(sets(i).Value.GetType) chk.Checked = sets(i).Value chk.TabIndex = tbIdx 'Setup the checkbox help string - for after clicking on the question mark button on the form hp1.SetHelpString(chk, "Toggles between true and false for this setting.") hp1.SetShowHelp(chk, True) 'Add the handler for the checkbox, and add it to the form AddHandler chk.LostFocus, AddressOf checkbox_handler ntlp.Controls.Add(chk) ElseIf TypeOf (sets(i).Value) Is Date Then 'If the setting is a date use a datetimepicker for editing 'Setup the label lbl.Text = sets(i).Name 'Add the label ntlp.Controls.Add(lbl) ntlp.RowStyles.Add(x) 'Setup the datetimepicker Dim dtp As New DateTimePicker dtp.Name = sets(i).TrueName dtp.Tag = GetTypeAbbr(sets(i).Value.GetType) dtp.Value = sets(i).Value dtp.Anchor = AnchorStyles.Left + AnchorStyles.Right + AnchorStyles.Top dtp.TabIndex = tbIdx 'Setup the datetimepicker help string - for after clicking on the question mark button on the form hp1.SetHelpString(dtp, "Drop-down that allows you to choose a date for this setting.") hp1.SetShowHelp(dtp, True) 'Add the handler for the datetimepicker, and add it to the form AddHandler dtp.LostFocus, AddressOf datetimepicker_handler ntlp.Controls.Add(dtp) ElseIf IsTxtType(sets(i).Value.GetType) Then 'If the setting is a type we edit with a textbox use a textbox for editing 'Setup the label lbl.Text = sets(i).Name 'Add the label ntlp.Controls.Add(lbl) ntlp.RowStyles.Add(x) 'Setup the textbox Dim txt As New TextBox txt.Name = sets(i).TrueName 'If the name contains the word Password - make the textbox mask the characters If sets(i).Name.ToLower.Contains("password") Then txt.PasswordChar = "*" txt.Tag = GetTypeAbbr(sets(i).Value.GetType) txt.Text = sets(i).Value txt.Anchor = AnchorStyles.Left + AnchorStyles.Right + AnchorStyles.Top txt.TabIndex = tbIdx 'Setup the textbox help string - for after clicking on the question mark button on the form 'Uses GetTypeName for type specific messages hp1.SetHelpString(txt, "Text entry field that allows you to enter " & GetTypeName(sets(i).Value.GetType) & " value for this setting.") hp1.SetShowHelp(txt, True) 'Add the handler for the textbox, and add it to the form AddHandler txt.LostFocus, AddressOf textbox_handler ntlp.Controls.Add(txt) ElseIf TypeOf (sets(i).Value) Is Color Then 'If the setting is a color use a button with no text for editing 'Setup the label lbl.Text = sets(i).Name 'Add the label ntlp.Controls.Add(lbl) ntlp.RowStyles.Add(x) 'Setup the button Dim cmd As New Button cmd.Name = sets(i).TrueName cmd.Tag = GetTypeAbbr(sets(i).Value.GetType) cmd.BackColor = sets(i).Value cmd.TabIndex = tbIdx 'Setup the button help string - for after clicking on the question mark button on the form hp1.SetHelpString(cmd, "Button that allows you to choose a color for this setting.") hp1.SetShowHelp(cmd, True) 'Add the handlers for the button, and add it to the form AddHandler cmd.Click, AddressOf button_click AddHandler cmd.LostFocus, AddressOf button_handler ntlp.Controls.Add(cmd) ElseIf TypeOf (sets(i).Value) Is Font Then 'If the setting is a font use a button with the font name for editing 'Setup the label lbl.Text = sets(i).Name 'Add the label ntlp.Controls.Add(lbl) ntlp.RowStyles.Add(x) 'Setup the button Dim cmd As New Button cmd.AutoSize = True cmd.Name = sets(i).TrueName cmd.Tag = GetTypeAbbr(sets(i).Value.GetType) cmd.Text = CType(sets(i).Value, Font).Name cmd.Font = sets(i).Value cmd.UseVisualStyleBackColor = True cmd.TabIndex = tbIdx 'Setup the button help string - for after clicking on the question mark button on the form hp1.SetHelpString(cmd, "Button that allows you to choose a font for this setting.") hp1.SetShowHelp(cmd, True) 'Add the handlers for the button, and add it to the form AddHandler cmd.Click, AddressOf button_click AddHandler cmd.LostFocus, AddressOf button_handler ntlp.Controls.Add(cmd) '##### enum type ElseIf TypeOf (sets(i).Value) Is [Enum] Then 'If the setting is a enum type we fill a combobox 'Setup the label lbl.Text = sets(i).Name 'Add the label ntlp.Controls.Add(lbl) ntlp.RowStyles.Add(x) 'Setup the ComboBox Dim cbo As New ComboBox cbo.DropDownStyle = ComboBoxStyle.DropDownList cbo.Name = sets(i).TrueName cbo.Tag = GetTypeAbbr(sets(i).Value.GetType) For Each o As Object In [Enum].GetValues(sets(i).Value.GetType) cbo.Items.Add(o) Next cbo.SelectedIndex = sets(i).Value cbo.Anchor = AnchorStyles.Left + AnchorStyles.Right + AnchorStyles.Top cbo.TabIndex = tbIdx 'Setup the help string - for after clicking on the question mark button on the form hp1.SetHelpString(cbo, "ComboBox that allows you to enter values of type " & sets(i).Value.GetType.FullName & " for this setting.") hp1.SetShowHelp(cbo, True) 'Add the handler for the Combobox, and add it to the form AddHandler cbo.LostFocus, AddressOf enum_handler ntlp.Controls.Add(cbo) End If 'Don't keep the label at autosize - remember it's most likely docked lbl.AutoSize = False 'Increment the TabIndex tbIdx += 1 Next 'Update the TabIndex of controls already on the form chkSaveOnExit.TabIndex = tbIdx + 1 cmdOK.TabIndex = tbIdx + 2 cmdCancel.TabIndex = tbIdx + 3 cmdApply.TabIndex = tbIdx + 4 End Sub
#End Region
#Region " TreeView Handling " ''' <summary> ''' Clears all the setting controls that were created at runtime from the window. ''' </summary> Private Sub ClearOptions() 'Cleans up the dynamically added controls for the settings Dim ctrl As Control 'While there are still dynamic controls on the form - remove them While tlp.Controls.Count > 0 'Set an object equal to a reference of the control ctrl = tlp.Controls.Item(0) 'Remove the handlers based on the type of the control If TypeOf (ctrl) Is Button Then RemoveHandler ctrl.Click, AddressOf button_click RemoveHandler ctrl.LostFocus, AddressOf button_handler ElseIf TypeOf (ctrl) Is CheckBox Then RemoveHandler ctrl.LostFocus, AddressOf checkbox_handler ElseIf TypeOf (ctrl) Is DateTimePicker Then RemoveHandler ctrl.LostFocus, AddressOf datetimepicker_handler ElseIf TypeOf (ctrl) Is TextBox Then RemoveHandler ctrl.LostFocus, AddressOf textbox_handler End If 'Remove the control from the form ctrl.Dispose() End While End Sub ''' <summary> ''' Determines whether the type passed would use a textbox or not. ''' </summary> ''' <param name="typ">A system type that you wish to check.</param> ''' <returns>Boolean: True the type does use a textbox, false it doesn't use a textbox.</returns> Private Function IsTxtType(ByVal typ As Type) As Boolean 'If the type passed is one of these we use a textbox to edit it If GetType(Byte) Is typ Or _ GetType(Char) Is typ Or _ GetType(Decimal) Is typ Or _ GetType(Double) Is typ Or _ GetType(Integer) Is typ Or _ GetType(Long) Is typ Or _ GetType(SByte) Is typ Or _ GetType(Short) Is typ Or _ GetType(Single) Is typ Or _ GetType(String) Is typ Or _ GetType(UInteger) Is typ Or _ GetType(ULong) Is typ Or _ GetType(UShort) Is typ Then Return True End If 'We don't use a textbox on this type. Return False End Function Private Sub tvCategories_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles tvCategories.AfterSelect 'A category was selected - clear the current display ClearOptions() tlp.RowStyles.Clear() tlp.RowCount = 1 'Reset the TabIndex for the dynamic controls Dim tbIdx As Integer = 1 'Get all the settings that match this category Dim sets() As SettingInfo = Settings.GetByCategory(tvCategories.SelectedNode.FullPath) 'If there aren't any we must exit If sets Is Nothing Then Exit Sub 'Some declaration to make things easier in the loop Dim lbl As Label = Nothing Dim dc1 As DockStyle = DockStyle.Fill Dim dc2 As DockStyle = DockStyle.None Dim x As RowStyle 'Cycle through this category's settings For i As Integer = 0 To UBound(sets) lbl = New Label x = New RowStyle x.SizeType = SizeType.AutoSize lbl.AutoSize = True 'If we've reached the end of the settings - don't use the Fill DockStyle. If i = UBound(sets) Then lbl.Dock = dc2 Else lbl.Dock = dc1 lbl.TextAlign = ContentAlignment.MiddleLeft If TypeOf (sets(i).Value) Is Boolean Then 'If the setting is a boolean use a checkbox for editing 'Setup the label lbl.Text = sets(i).Name 'Add the label tlp.Controls.Add(lbl) tlp.RowStyles.Add(x) 'Setup the checkbox Dim chk As New CheckBox chk.Name = sets(i).TrueName chk.Tag = GetTypeAbbr(sets(i).Value.GetType) chk.Checked = sets(i).Value chk.TabIndex = tbIdx 'Setup the checkbox help string - for after clicking on the question mark button on the form hp1.SetHelpString(chk, "Toggles between true and false for this setting.") hp1.SetShowHelp(chk, True) 'Add the handler for the checkbox, and add it to the form AddHandler chk.LostFocus, AddressOf checkbox_handler tlp.Controls.Add(chk) ElseIf TypeOf (sets(i).Value) Is Date Then 'If the setting is a date use a datetimepicker for editing 'Setup the label lbl.Text = sets(i).Name 'Add the label tlp.Controls.Add(lbl) tlp.RowStyles.Add(x) 'Setup the datetimepicker Dim dtp As New DateTimePicker dtp.Name = sets(i).TrueName dtp.Tag = GetTypeAbbr(sets(i).Value.GetType) dtp.Value = sets(i).Value dtp.Anchor = AnchorStyles.Left + AnchorStyles.Right + AnchorStyles.Top dtp.TabIndex = tbIdx 'Setup the datetimepicker help string - for after clicking on the question mark button on the form hp1.SetHelpString(dtp, "Drop-down that allows you to choose a date for this setting.") hp1.SetShowHelp(dtp, True) 'Add the handler for the datetimepicker, and add it to the form AddHandler dtp.LostFocus, AddressOf datetimepicker_handler tlp.Controls.Add(dtp) ElseIf IsTxtType(sets(i).Value.GetType) Then 'If the setting is a type we edit with a textbox use a textbox for editing 'Setup the label lbl.Text = sets(i).Name 'Add the label tlp.Controls.Add(lbl) tlp.RowStyles.Add(x) 'Setup the textbox Dim txt As New TextBox txt.Name = sets(i).TrueName 'If the name contains the word Password - make the textbox mask the characters If sets(i).Name.ToLower.Contains("password") Then txt.PasswordChar = "*" txt.Tag = GetTypeAbbr(sets(i).Value.GetType) txt.Text = sets(i).Value txt.Anchor = AnchorStyles.Left + AnchorStyles.Right + AnchorStyles.Top txt.TabIndex = tbIdx 'Setup the textbox help string - for after clicking on the question mark button on the form 'Uses GetTypeName for type specific messages hp1.SetHelpString(txt, "Text entry field that allows you to enter " & GetTypeName(sets(i).Value.GetType) & " value for this setting.") hp1.SetShowHelp(txt, True) 'Add the handler for the textbox, and add it to the form AddHandler txt.LostFocus, AddressOf textbox_handler tlp.Controls.Add(txt) ElseIf TypeOf (sets(i).Value) Is Color Then 'If the setting is a color use a button with no text for editing 'Setup the label lbl.Text = sets(i).Name 'Add the label tlp.Controls.Add(lbl) tlp.RowStyles.Add(x) 'Setup the button Dim cmd As New Button cmd.Name = sets(i).TrueName cmd.Tag = GetTypeAbbr(sets(i).Value.GetType) cmd.BackColor = sets(i).Value cmd.TabIndex = tbIdx 'Setup the button help string - for after clicking on the question mark button on the form hp1.SetHelpString(cmd, "Button that allows you to choose a color for this setting.") hp1.SetShowHelp(cmd, True) 'Add the handlers for the button, and add it to the form AddHandler cmd.Click, AddressOf button_click AddHandler cmd.LostFocus, AddressOf button_handler tlp.Controls.Add(cmd) ElseIf TypeOf (sets(i).Value) Is Font Then 'If the setting is a font use a button with the font name for editing 'Setup the label lbl.Text = sets(i).Name 'Add the label tlp.Controls.Add(lbl) tlp.RowStyles.Add(x) 'Setup the button Dim cmd As New Button cmd.AutoSize = True cmd.Name = sets(i).TrueName cmd.Tag = GetTypeAbbr(sets(i).Value.GetType) cmd.Text = CType(sets(i).Value, Font).Name cmd.Font = sets(i).Value cmd.UseVisualStyleBackColor = True cmd.TabIndex = tbIdx 'Setup the button help string - for after clicking on the question mark button on the form hp1.SetHelpString(cmd, "Button that allows you to choose a font for this setting.") hp1.SetShowHelp(cmd, True) 'Add the handlers for the button, and add it to the form AddHandler cmd.Click, AddressOf button_click AddHandler cmd.LostFocus, AddressOf button_handler tlp.Controls.Add(cmd) '##### enum type ElseIf TypeOf (sets(i).Value) Is [Enum] Then 'If the setting is a enum type we fill a combobox 'Setup the label lbl.Text = sets(i).Name 'Add the label tlp.Controls.Add(lbl) tlp.RowStyles.Add(x) 'Setup the ComboBox Dim cbo As New ComboBox cbo.DropDownStyle = ComboBoxStyle.DropDownList cbo.Name = sets(i).TrueName cbo.Tag = GetTypeAbbr(sets(i).Value.GetType) For Each o As Object In [Enum].GetValues(sets(i).Value.GetType) cbo.Items.Add(o) Next cbo.SelectedIndex = sets(i).Value cbo.Anchor = AnchorStyles.Left + AnchorStyles.Right + AnchorStyles.Top cbo.TabIndex = tbIdx 'Setup the help string - for after clicking on the question mark button on the form hp1.SetHelpString(cbo, "ComboBox that allows you to enter values of type " & sets(i).Value.GetType.FullName & " for this setting.") hp1.SetShowHelp(cbo, True) 'Add the handler for the Combobox, and add it to the form AddHandler cbo.LostFocus, AddressOf enum_handler tlp.Controls.Add(cbo) End If 'Don't keep the label at autosize - remember it's most likely docked lbl.AutoSize = False 'Increment the TabIndex tbIdx += 1 Next 'Update the TabIndex of controls already on the form chkSaveOnExit.TabIndex = tbIdx + 1 cmdOK.TabIndex = tbIdx + 2 cmdCancel.TabIndex = tbIdx + 3 cmdApply.TabIndex = tbIdx + 4 End Sub ''' <summary> ''' Gets the four letter type abbreviation for the passed type. ''' </summary> ''' <param name="typ">A system type that you wish to get the four letter type for.</param> ''' <returns>String containing the four letter abbrieviation for the type.</returns> ''' <remarks>Some are 3 letters with a space in front to make it four characters.</remarks> Private Function GetTypeAbbr(ByVal typ As Type) As String 'Get a four character string to represent the type 'This goes in the tag of the dynamic control and helps 'the handlers determine what type to check for in textboxes 'and buttons. If GetType(Boolean) Is typ Then Return "bool" ElseIf GetType(Byte) Is typ Then Return "byte" ElseIf GetType(Char) Is typ Then Return "char" ElseIf GetType(Date) Is typ Then Return "date" ElseIf GetType(Decimal) Is typ Then Return " dec" ElseIf GetType(Double) Is typ Then Return " dbl" ElseIf GetType(Integer) Is typ Then Return " int" ElseIf GetType(Long) Is typ Then Return "long" ElseIf GetType(SByte) Is typ Then Return "sbyt" ElseIf GetType(Short) Is typ Then Return "shrt" ElseIf GetType(Single) Is typ Then Return "sngl" ElseIf GetType(String) Is typ Then Return " str" ElseIf GetType(Color) Is typ Then Return " clr" ElseIf GetType(Font) Is typ Then Return "font" ElseIf GetType(UInteger) Is typ Then Return "uint" ElseIf GetType(ULong) Is typ Then Return "ulng" ElseIf GetType(UShort) Is typ Then Return "usht" End If Return Nothing End Function ''' <summary> ''' Gets a string containing the type name with a describing article (a, an, the) for display in a MsgBox ''' </summary> ''' <param name="typ">A system type that you wish to get the name of.</param> ''' <returns>String containing the name of the type and an article for describing it.</returns> Private Function GetTypeName(ByVal typ As Type) As String 'Gets a string for the message box error message when trying to determine 'if a setting was set properly If GetType(Boolean) Is typ Then Return "a Boolean" ElseIf GetType(Byte) Is typ Then Return "a Byte" ElseIf GetType(Char) Is typ Then Return "a Character" ElseIf GetType(Date) Is typ Then Return "a Date" ElseIf GetType(Decimal) Is typ Then Return "a Decimal (numeric)" ElseIf GetType(Double) Is typ Then Return "a Double (numeric)" ElseIf GetType(Integer) Is typ Then Return "an Integer (numeric)" ElseIf GetType(Long) Is typ Then Return "a Long (numeric)" ElseIf GetType(SByte) Is typ Then Return "a Short Byte" ElseIf GetType(Short) Is typ Then Return "a Short (numeric)" ElseIf GetType(Single) Is typ Then Return "a Single (numeric)" ElseIf GetType(String) Is typ Then Return "a String (text)" ElseIf GetType(Color) Is typ Then Return "a Color" ElseIf GetType(Font) Is typ Then Return "a Font" ElseIf GetType(UInteger) Is typ Then Return "an Unsigned Integer (numeric)" ElseIf GetType(ULong) Is typ Then Return "an Unsigned Long (numeric)" ElseIf GetType(UShort) Is typ Then Return "an Unsigned Short (numeric)" End If Return Nothing End Function #End Region
#Region " Property Handlers " 'checkbox, datetimepicker, textbox, button 'Handlers do not apply the values they set - just update the collection '##### enum types Private Sub enum_handler(ByVal sender As Object, ByVal e As System.EventArgs) Settings.SetEnumByTrueName(sender.Name, sender.text) End Sub Private Sub checkbox_handler(ByVal sender As Object, ByVal e As System.EventArgs) 'Checkboxes can only be boolean - update the setting in the collection Settings.SetValueByTrueName(sender.Name, sender.Checked) End Sub Private Sub datetimepicker_handler(ByVal sender As Object, ByVal e As System.EventArgs) 'the datetimepicker can only be a date - so update the collection Settings.SetValueByTrueName(sender.Name, sender.Value) End Sub Private Sub textbox_handler(ByVal sender As Object, ByVal e As System.EventArgs) 'byte, char, decimal, double, integer, long, sbyte, short, single, string, uinteger, ulong, ushort 'is a list of everything that a textbox could contain 'check the value in the textbox to make sure it 'is of the correct type before adding it to the 'collection - if it's not the correct type tell the 'user so and select the offending value If CType(sender.Tag, String) = GetTypeAbbr(GetType(Byte)) Then Dim x As Byte = Nothing If Byte.TryParse(sender.Text, x) Then Settings.SetValueByTrueName(sender.Name, x) Else MsgBox("Could not convert " & sender.Text & " to a Byte.", MsgBoxStyle.Exclamation) sender.Focus() sender.SelectAll() End If ElseIf CType(sender.Tag, String) = GetTypeAbbr(GetType(Char)) Then Dim x As Char = Nothing If Char.TryParse(sender.Text, x) Then Settings.SetValueByTrueName(sender.Name, x) Else MsgBox("Could not convert " & sender.Text & " to a Char.", MsgBoxStyle.Exclamation) sender.Focus() sender.SelectAll() End If ElseIf CType(sender.Tag, String) = GetTypeAbbr(GetType(Decimal)) Then Dim x As Decimal = Nothing If Decimal.TryParse(sender.Text, x) Then Settings.SetValueByTrueName(sender.Name, x) Else MsgBox("Could not convert " & sender.Text & " to a Decimal.", MsgBoxStyle.Exclamation) sender.Focus() sender.SelectAll() End If ElseIf CType(sender.Tag, String) = GetTypeAbbr(GetType(Double)) Then Dim x As Double = Nothing If Double.TryParse(sender.Text, x) Then Settings.SetValueByTrueName(sender.Name, x) Else MsgBox("Could not convert " & sender.Text & " to a Double.", MsgBoxStyle.Exclamation) sender.Focus() sender.SelectAll() End If ElseIf CType(sender.Tag, String) = GetTypeAbbr(GetType(Integer)) Then Dim x As Integer = Nothing If Integer.TryParse(sender.Text, x) Then Settings.SetValueByTrueName(sender.Name, x) Else MsgBox("Could not convert " & sender.Text & " to a Integer.", MsgBoxStyle.Exclamation) sender.Focus() sender.SelectAll() End If ElseIf CType(sender.Tag, String) = GetTypeAbbr(GetType(Long)) Then Dim x As Long = Nothing If Long.TryParse(sender.Text, x) Then Settings.SetValueByTrueName(sender.Name, x) Else MsgBox("Could not convert " & sender.Text & " to a Long.", MsgBoxStyle.Exclamation) sender.Focus() sender.SelectAll() End If ElseIf CType(sender.Tag, String) = GetTypeAbbr(GetType(SByte)) Then Dim x As SByte = Nothing If SByte.TryParse(sender.Text, x) Then Settings.SetValueByTrueName(sender.Name, x) Else MsgBox("Could not convert " & sender.Text & " to a SByte.", MsgBoxStyle.Exclamation) sender.Focus() sender.SelectAll() End If ElseIf CType(sender.Tag, String) = GetTypeAbbr(GetType(Short)) Then Dim x As Short = Nothing If Short.TryParse(sender.Text, x) Then Settings.SetValueByTrueName(sender.Name, x) Else MsgBox("Could not convert " & sender.Text & " to a Short.", MsgBoxStyle.Exclamation) sender.Focus() sender.SelectAll() End If ElseIf CType(sender.Tag, String) = GetTypeAbbr(GetType(Single)) Then Dim x As Single = Nothing If Single.TryParse(sender.Text, x) Then Settings.SetValueByTrueName(sender.Name, x) Else MsgBox("Could not convert " & sender.Text & " to a Single.", MsgBoxStyle.Exclamation) sender.Focus() sender.SelectAll() End If ElseIf CType(sender.Tag, String) = GetTypeAbbr(GetType(String)) Then Settings.SetValueByTrueName(sender.Name, sender.Text) ElseIf CType(sender.Tag, String) = GetTypeAbbr(GetType(UInteger)) Then Dim x As UInteger = Nothing If UInteger.TryParse(sender.Text, x) Then Settings.SetValueByTrueName(sender.Name, x) Else MsgBox("Could not convert " & sender.Text & " to a UInteger.", MsgBoxStyle.Exclamation) sender.Focus() sender.SelectAll() End If ElseIf CType(sender.Tag, String) = GetTypeAbbr(GetType(ULong)) Then Dim x As ULong = Nothing If ULong.TryParse(sender.Text, x) Then Settings.SetValueByTrueName(sender.Name, x) Else MsgBox("Could not convert " & sender.Text & " to a ULong.", MsgBoxStyle.Exclamation) sender.Focus() sender.SelectAll() End If ElseIf CType(sender.Tag, String) = GetTypeAbbr(GetType(UShort)) Then Dim x As UShort = Nothing If UShort.TryParse(sender.Text, x) Then Settings.SetValueByTrueName(sender.Name, x) Else MsgBox("Could not convert " & sender.Text & " to a UShort.", MsgBoxStyle.Exclamation) sender.Focus() sender.SelectAll() End If End If End Sub Private Sub button_click(ByVal sender As Object, ByVal e As System.EventArgs) 'Buttons can contain either a Font, or a color 'check which it is and bring up the appropriate dialog 'box for editing If CType(sender.Tag, String) = GetTypeAbbr(GetType(Color)) Then dlgColor.Color = sender.BackColor If dlgColor.ShowDialog = Windows.Forms.DialogResult.OK Then sender.BackColor = dlgColor.Color ElseIf CType(sender.Tag, String) = GetTypeAbbr(GetType(Font)) Then dlgFont.Font = CType(sender, Button).Font If dlgFont.ShowDialog = Windows.Forms.DialogResult.OK Then sender.Font = dlgFont.Font sender.Text = dlgFont.Font.Name End If End If End Sub Private Sub button_handler(ByVal sender As Object, ByVal e As System.EventArgs) 'Buttons can contain either a Font, or a color 'check which it is to make sure we're updating 'the correct value If CType(sender.Tag, String) = GetTypeAbbr(GetType(Color)) Then Settings.SetValueByTrueName(sender.Name, sender.BackColor) ElseIf CType(sender.Tag, String) = GetTypeAbbr(GetType(Font)) Then Settings.SetValueByTrueName(sender.Name, sender.Font) End If End Sub #End Region
#Region " Button Clicks "
Private Sub cmdApply_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdApply.Click ApplySettings() 'Apply the settings don't save, let the application save when it exits End Sub
Private Sub cmdOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdOK.Click '##### 'if cmdOK_Click is called by pressing Return/Enter key set the focus to cmdOK, so that LostFocus is called ' and the value is copied to settings cmdOK.Focus() ApplySettings() 'Apply the settings don't save, let the application save when it exits 'Tell the dialog it can close and everything is ok Me.DialogResult = Windows.Forms.DialogResult.OK End Sub ''' <summary> ''' Applies the settings in the SettingInfoCollection to the actual setting in the My namespace. ''' </summary> Private Sub ApplySettings() 'Cycle through each setting that we could edit and 'update the real setting contained in the My namespace For Each si As SettingInfo In Settings My.Settings.Item(si.TrueName) = si.Value Next 'Update the SaveOnExit value My.Application.SaveMySettingsOnExit = chkSaveOnExit.Checked End Sub
#End Region
End Class
Public Class SettingCategory Public MainCat As String Public SubCats As String End Class Public Class SettingCategoryCollection Inherits CollectionBase
Public Sub Add(ByVal item As SettingCategory) List.Add(item) End Sub
Default ReadOnly Property Item(ByVal index As Integer) As SettingCategory Get Return CType(List.Item(index), SettingCategory) End Get End Property
Public Function IndexOf(ByVal name As String, ByVal subc As String) As Integer For i As Integer = 0 To Count - 1 If CType(List.Item(i), SettingCategory).MainCat = name And CType(List.Item(i), SettingCategory).SubCats = subc Then Return i Next Return -1 End Function End Class Public Class SettingInfo
Private _Name As String ''' <summary> ''' The display name of the setting. ''' </summary> ''' <value>The display name for the setting</value> ''' <returns>The display name for the setting</returns> Public Property Name() As String Get Return _Name End Get Set(ByVal value As String) _Name = value End Set End Property
Private _Category As String ''' <summary> ''' The category to which the setting belongs. ''' </summary> ''' <value>The category to which the setting belongs</value> ''' <returns>The dot seperated category/sub-category to which the setting belongs</returns> Public ReadOnly Property Category() As String Get Return _Category End Get End Property ''' <summary> ''' Sets the category based on an array of the categories/sub-categories. ''' </summary> ''' <param name="values">The category/sub-category list. Index 0 is the category and the sub-categories follow.</param> Public Sub SetCategory(ByVal values() As String) 'The category should contain a dot separated list of values - implode does this nicely _Category = implode(".", values) End Sub ''' <summary> ''' Sets the category to the string provided. ''' </summary> ''' <param name="value">The actual dot separated category/sub-category list. (ex Category1.SubCat1.SubCat2)</param> Public Sub SetCategory(ByVal value As String) 'If the value is already in dot separated format just updated (doesn't check) _Category = value End Sub ''' <summary> ''' Takes an array of values and concatenates them separating each item in the array with the value in chr. ''' </summary> ''' <param name="chr">A character or string which separates the values in "values".</param> ''' <param name="values">An array of strings to be concatenated and separated by chr.</param> ''' <returns>A string containing all the values in the array provided concatenated and separated by the value in chr.</returns> Private Function implode(ByVal chr As String, ByVal values() As String) As String 'Taken from the php function implode 'Setup an empty string for building Dim tmp As String = Nothing 'Cycle through the array For Each str As String In values 'Add the current value and the separator to the string tmp &= str & chr Next 'The result has an extra delimiter on the end remove it tmp = tmp.TrimEnd(chr) 'Return the finished result Return tmp End Function
''' <summary> ''' Loads a My.Settings setting name into the current SettingInfo object. ''' </summary> ''' <param name="str">A My.Settings name in the following format (Category_SubCategory1_SubCategory2_etc..._Setting__Name_SortIndex).</param> ''' <remarks>A single underscore separates the categories, name, and sort index. A double underscore signifies a space. Not providing a sort index, will give the setting a sort index of -1.</remarks> Public Sub LoadData(ByVal str As String) 'Replace the double underscore with a space to allow the window 'to show multi-word Settings names str = str.Replace("__", " ") 'Check if the last value (separated by underscores) is numeric If MyNumeric(str.Substring(str.LastIndexOf("_") + 1)) Then 'It is numeric - so use it as the SortIndex _Sort = Integer.Parse(str.Substring(str.LastIndexOf("_") + 1)) 'Remove it from the string str = str.Substring(0, str.LastIndexOf("_")) Else 'Not numeric assign default SortIndex of -1 _Sort = -1 End If 'Assign the name of the setting - should be that last value in the string _Name = str.Substring(str.LastIndexOf("_") + 1) 'Get the category string (don't include the name) Dim cat As String = str.Substring(0, str.LastIndexOf("_")) 'Assign the category (SetCategory takes a string array so use split) SetCategory(cat.Split("_")) 'Get the value from the My namespace and assign it _Value = My.Settings.Item(TrueName) End Sub ''' <summary> ''' Checks if the string is a pure numeric value. ''' </summary> ''' <param name="val">A string containing the value to be checked.</param> ''' <returns>True if the value is numeric, false if the value isn't numeric.</returns> ''' <remarks>Cycles through each character in the value passed and checks if it is one of the following: 1234567890. If it's not the value isn't numeric and it returns false.</remarks> Private Function MyNumeric(ByVal val As String) As Boolean 'Create a string array for valid characters of a numeric string Dim chr() As String = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0"} 'Check each character in the passed value For i As Integer = 0 To val.Length - 1 If Array.IndexOf(chr, val.Substring(i, 1)) = -1 Then Return False 'Not a number Next 'Successfully made it through the test - it is a number Return True End Function
Private _Sort As Integer ''' <summary> ''' The SortIndex of the setting name. Determines where the setting will be display on the form once it's category is selected. ''' </summary> ''' <value>Integer</value> ''' <returns>Integer</returns> Public Property SortIndex() As Integer Get Return _Sort End Get Set(ByVal value As Integer) _Sort = value End Set End Property
Private _Value As Object ''' <summary> ''' The value of the setting. Could be any object type from boolean to font. ''' </summary> ''' <value>Object containing the settings value.</value> ''' <returns>Object containing the settings value.</returns> Public Property Value() As Object Get Return _Value End Get Set(ByVal value As Object) _Value = value End Set End Property
''' <summary> ''' The true name of the setting. Computes the original setting name from the category, name, and sort index. ''' </summary> ''' <returns>String containing the true setting name.</returns> Public ReadOnly Property TrueName() As String 'Rebuilds the original setting name as specified in the My namespace Get 'Create temporary string and give it the value of the category replacing the periods with underscores 'Also add the name onto the end of it Dim tmp As String = _Category.Replace(".", "_") & "_" & _Name 'If there is a valid SortIndex - add that to the end as well If _Sort <> -1 Then tmp &= "_" & SortIndex 'Return a value with no spaces (use double underscores instead) Return tmp.Replace(" ", "__") End Get End Property
''' <summary> ''' Clones the current SettingInfo object to another variable. ''' </summary> ''' <returns>A copy of the current SettingInfo object.</returns> Public Function Clone() As SettingInfo 'Build a copy of this SettingInfo and return it Dim tmp As New SettingInfo tmp.Name = _Name tmp.SetCategory(_Category) tmp.SortIndex = _Sort tmp.Value = _Value Return tmp End Function End Class Public Class SettingInfoCollection Inherits CollectionBase
''' <summary> ''' Adds a SettingInfo object to the collection. ''' </summary> ''' <param name="item">A SettingInfo object</param> Public Sub Add(ByVal item As SettingInfo) 'Add the item to the list List.Add(item) End Sub
''' <summary> ''' Returns a specific element of the collection by position. Read-only. ''' </summary> ''' <param name="index">A numeric expression that specifies the position of an element of the collection. Index must be a number from 0 through the value of the Collection's Count Property.</param> ''' <returns>A SettingInfo object from the position specified.</returns> Default Public ReadOnly Property Item(ByVal index As Integer) As SettingInfo Get 'Return the selected item (make sure it is the correct type) Return CType(List.Item(index), SettingInfo) End Get End Property
''' <summary> ''' Sets the values of a SettingInfo object already in the collection. ''' </summary> ''' <param name="index">A numeric expression that specifies the position of an element you wish to change in the collection. Index must be a number from 0 through the value of the Collection's Count Property.</param> ''' <param name="value">A SettingInfo object that contains the values you wish to set to the element specified by Index.</param> Public Sub SetItem(ByVal index As Integer, ByVal value As SettingInfo) 'Update an item already in the collection, must do it one value at a time 'otherwise we just get a reference CType(List.Item(index), SettingInfo).SetCategory(value.Category) CType(List.Item(index), SettingInfo).Name = value.Name CType(List.Item(index), SettingInfo).Value = value.Value CType(List.Item(index), SettingInfo).SortIndex = value.SortIndex End Sub
''' <summary> ''' Get's all the SettingInfo objects in the collection that have the same category as the one specified. ''' </summary> ''' <param name="category">A string expression that specifies the category of the elements to retrieve. Category must be in the dot separated format used by the SettingInfo objects (ex. Category.SubCategory.SubCat2)</param> ''' <returns>An array of SettingInfo objects that match the category specified.</returns> Public Function GetByCategory(ByVal category As String) As SettingInfo() 'Create and empty array used for return the found data Dim tmp() As SettingInfo = Nothing 'An integer to store the current array index Dim iT As Integer = 0 'A boolean to tell us if we need to sort it Dim sortIt As Boolean = False 'Cycle through all the settings For si As Integer = 0 To Count - 1 'Does the category match? If CType(List.Item(si), SettingInfo).Category = category Then 'Yes - Initialize current array itemj ReDim Preserve tmp(iT) 'If the SortIndex isn't default (-1) then we need to sort the entire array when done If CType(List.Item(si), SettingInfo).SortIndex <> -1 Then sortIt = True 'Copy the item to the array tmp(iT) = List.Item(si) 'Increment the index iT += 1 End If Next 'Do we need to sort it? If sortIt Then 'Yes - call the quicksort subroutine for this array Me.SortIt(tmp, 0, UBound(tmp)) End If 'Return the sorted (if necessary) array Return tmp End Function
''' <summary> ''' Get's all the SettingInfo objects in the collection that have the same category as the one specified. ''' </summary> ''' <param name="cat">A string expression that specifies the category of the elements to retrieve. Category must be in the dot separated format used by the SettingInfo objects (ex. Category.SubCategory.SubCat2)</param> ''' <returns>An array of SettingInfo objects that match the category specified.</returns> ''' <remarks>Used only for the TabPages as the category could be condensed from the real form.</remarks> Public Function GetByTabCategory(ByVal cat As String) As SettingInfo() 'Create and empty array used for return the found data Dim tmp() As SettingInfo = Nothing 'An integer to store the current array index Dim iT As Integer = 0 'A boolean to tell us if we need to sort it Dim sortIt As Boolean = False 'Cycle through all the settings For si As Integer = 0 To Count - 1 'Does the category match? If CType(List.Item(si), SettingInfo).Category.StartsWith(cat) Then 'Yes - Initialize current array itemj ReDim Preserve tmp(iT) 'If the SortIndex isn't default (-1) then we need to sort the entire array when done If CType(List.Item(si), SettingInfo).SortIndex <> -1 Then sortIt = True 'Copy the item to the array tmp(iT) = List.Item(si) 'Increment the index iT += 1 End If Next 'Do we need to sort it? If sortIt Then 'Yes - call the quicksort subroutine for this array Me.SortIt(tmp, 0, UBound(tmp)) End If 'Return the sorted (if necessary) array Return tmp End Function
Public Function GetCategories() As SettingCategoryCollection Dim tmp As New SettingCategoryCollection Dim add As SettingCategory Dim name As String Dim subn As String For Each si As SettingInfo In List name = Nothing subn = Nothing If si.Category.IndexOf(".") = -1 Then name = si.Category Else name = si.Category.Substring(0, si.Category.IndexOf(".")) If si.Category.IndexOf(".") = -1 Then subn = Nothing Else subn = si.Category.Substring(si.Category.IndexOf(".")) If tmp.IndexOf(name, subn) = -1 Then add = New SettingCategory add.MainCat = name add.SubCats = subn tmp.Add(add) End If Next Return tmp End Function
''' <summary> ''' Sorts an array of SettingInfo objects by their SortIndex. ''' </summary> ''' <param name="SortArray">A reference to the array you wish to sort.</param> ''' <param name="First">The starting element of the selection you wish to sort (usually 0).</param> ''' <param name="Last">Then final element of the selection you wish to sort (usually the upper bound of the array).</param> ''' <remarks>Called from GetByCategory</remarks> Private Sub SortIt(ByRef SortArray() As SettingInfo, ByVal First As Long, ByVal Last As Long) 'Copied and modified from the SortIt method in the form Dim Low As Long, High As Long Dim Temp As SettingInfo = Nothing Dim List_Separator As SettingInfo = Nothing Low = First High = Last List_Separator = SortArray((First + Last) / 2).Clone Do Do While (SortArray(Low).SortIndex < List_Separator.SortIndex) Low += 1 Loop Do While (SortArray(High).SortIndex > List_Separator.SortIndex) High -= 1 Loop If (Low <= High) Then Temp = SortArray(Low).Clone SortArray(Low) = SortArray(High).Clone SortArray(High) = Temp.Clone Low += 1 High -= 1 End If Loop While (Low <= High) If (First < High) Then SortIt(SortArray, First, High) If (Low < Last) Then SortIt(SortArray, Low, Last) End Sub
''' <summary> ''' Sets the value of an SettingInfo object already in the collection by it's true name. ''' </summary> ''' <param name="name">The name of the setting as specified in the My.Settings object.</param> ''' <param name="value">The value you wish to set to the specified setting.</param> ''' <remarks>Called by the control handlers when the controls lose focus.</remarks> Public Sub SetValueByTrueName(ByVal name As String, ByVal value As Object) 'Loop through all items in the list For i As Integer = 0 To Count - 1 'Does the item's TrueName match the name passed? If CType(List(i), SettingInfo).TrueName = name Then 'Yes - then update the value and exit CType(List(i), SettingInfo).Value = value Exit Sub End If Next End Sub '##### enum types Public Sub SetEnumByTrueName(ByVal name As String, ByVal EnumText As String) 'Loop through all items in the list For i As Integer = 0 To Count - 1 'Does the item's TrueName match the name passed? If CType(List(i), SettingInfo).TrueName = name Then 'Yes - then update the value and exit CType(List(i), SettingInfo).Value = [Enum].Parse(CType(List(i), SettingInfo).Value.GetType, EnumText) Exit Sub End If Next End Sub End Class
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Thanks Peter,
I've updated the source to include enums.
I've also written an update for the article and submitted it along with new source files.
The source download will soon include enum support and FireFox1 & FireFox2 styles (easily add images too!).
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
OK let me start off by saying wowsers...nice very nice i really like that it automaticaly makes the settings on the form by editing the settings under properties. very nice indeed.
you didnt say how to use the information in a form heres a snip from the help via vb.net ---------------------------------------------- Sub ShowNickname() MsgBox("Nickname is " & My.Settings.Nickname) End Sub
For this example to work, your application must have a Nickname setting, of type String ---------------------------------------------------
and heres how to change it ----------------------------------------------- This example changes the value of the Nickname user setting.
Sub ChangeNickname(ByVal newNickname As String) My.Settings.Nickname = newNickname End Sub
For this example to work, your application must have a Nickname user setting, of type String. ------------------------------------------------------
thought youd like to see the vb.net version of how to set it up ------------------------------------------------------------ To add application settings in the Properties window Select a form or control in the Form Designer; on the View menu, click Properties Window.
In the Properties window, expand the (Application Settings) property (located under the Data node).
Select the (Property Binding) property and click the ellipsis button (...) to open the Application Settings dialog box.
In the Application Settings dialog box, select the property for which you wish to add an application setting.
In the drop-down list for the property, click (New...) to open the New Application Setting dialog box.
In the New Application Setting dialog box, select the Name property and enter a name for the setting. The name cannot contain spaces.
Select the DefaultValue property and enter a default value for the setting.
Select the scope of the setting from the Scope drop-down list. The setting's scope can be Application or User.
To bind the new setting to the property, select it from the drop-down list, then click OK.
The property binding will be added to the Properties window, and the new setting will be added to the Project Designer. Note that once you have created the setting, you must use the Project Designer to change it.
To remove application settings Select a project in Solution Explorer; on the Project menu, click Properties.
Select the Settings pane.
Click on the row in the Settings grid for the setting you wish to remove.
Press the Delete key, or right-click and select Remove Setting.
The setting will be removed from the Project Designer.
Note You will need to remove settings manually from app.config because the Project Designer does not remove any references to application settings in your code or its own code. -----------------------------------------------
again thanks alot for making it..im gonna alow the users to set the way it shows too..and a default of tabs..i like the treeview myself so this is great...
thx
-- modified at 9:06 Friday 25th November, 2005
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Well there are two ways to use the data that is saved.
First you can bind it to an object on the form (or the form itself). You do this by selecting the object you want to bind in the form designer and going (in the properties window) to ApplicationSettings. Expand that and you will find PropertyBindings (though the most common used bindings for that object are already visible), choose the "..." button for PropertyBindings to get a list of all the properties you can bind. Then from a drop-down list, choose the setting you wish to bind it too.
Second you can use direct assignment. You can do this from the My.Settings namespace. For each setting you create using the designer, it adds a setting to the namespace. So say you have a string setting named str_Test_Setting - you would assign that to a textbox like this: TextBox1.Text = My.Settings.str_Test_Setting. It's really that simple.
Yea it probably did hit me in the face... happens quite a bit now that I think about it - probably got numb off the feeling. 
Will definately work on updating that in the article as well.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|