The previous post in this series, Exploring the GrabAPicture Application (Part 10), discussed frmMain, which allows the user to perform application configuration and manually configure the Desktop wallpaper. The focus of this application, however, is automated configuration, which is the purview of frmConfigure—the topic of discussion today. The user relies on frmConfigure to add, edit, delete, and select either local or remote graphic sources for the Desktop wallpaper as shown here.
There are really two sets of four buttons here: the local set and the remote set. Each set performs the same sets of tasks with a different part of the same XML database. The information about this database appears in previous posts, but the main post of concern is Exploring the GrabAPicture Application (Part 8). When adding or editing a database element, the user sees a form similar to the one shown here:
Even though frmConfigure looks a little complex, there are really only three groups of tasks to perform:
- Load the current database
- Manage local database resources
- Manage remote database resources
Load the Current Database
The first task is to load the current database. In this case, the application creates and configures a global variable that provides access to the preconfigured wallpaper choices as shown here.
' Current application settings.
Dim
CurrentSettings
As
GrabAPictureSettings
Private
Sub
frmConfigure_Load(
ByVal
sender
As
Object
, _
ByVal
e
As
System.EventArgs) _
Handles
MyBase
.Load
' Initialize the stored settings.
CurrentSettings = GrabAPictureSettings.LoadSettings()
' Configure the controls.
If
Not
CurrentSettings
Is
Nothing
Then
If
Not
CurrentSettings.LocalUris
Is
Nothing
Then
For
Each
Item
As
LocalUri
In
CurrentSettings.LocalUris
lstLocal.Items.Add(Item.Name)
Next
End
If
If
Not
CurrentSettings.RemoteUris
Is
Nothing
Then
For
Each
Item
As
RemoteUri
In
CurrentSettings.RemoteUris
lstRemote.Items.Add(Item.Name)
Next
End
If
Else
' Define default settings.
CurrentSettings =
New
GrabAPictureSettings
End
If
End
Sub
The global variable, CurrentSettings, is of type GrabAPictureSettings. The application begins trying to fill CurrentSettings by calling GrabAPictureSettings.LoadSettings(). When this is the first application use and the user hasn’t added any wallpaper yet, the result of this call is that CurrentSettings equals Nothing, so the application creates a new database by creating a new GrabAPictureSettings database.
When there are settings to use, the application must determine which settings are available. The database may only contain local or remote settings, but not both. The next step determines whether CurrentSettings.LocalUris contains Nothing. If there are local settings, the application places the name of each of these entries in the lstLocal list box. The application performs a similar task for the remote settings. As a result, the user sees the names of all of the available local and remote wallpaper sources when the application dialog first appears on screen.
Manage Local Database Resources
After the form appears on screen, the user sees the local resources at the top of the form in the Local Sources list. The user can add, edit, delete, or select local resources using the associated controls as shown here:
Private
Sub
btnLAdd_Click(
ByVal
sender
As
System.
Object
, _
ByVal
e
As
System.EventArgs) _
Handles
btnLAdd.Click
' Create a form to add the record.
Dim
AddItem
As
New
frmAddEdit
' Set the resources when available.
If
Not
CurrentSettings.LocalUris
Is
Nothing
Then
AddItem.Resources = CurrentSettings.LocalUris
End
If
' If the user makes changes, add the information to
' the settings database and display it on screen.
If
AddItem.ShowDialog(
Me
) = DialogResult.OK
Then
CurrentSettings.LocalUris = AddItem.Resources
GrabAPictureSettings.SaveSettings(CurrentSettings)
lstLocal.Items.Add(AddItem.Resources(AddItem.Resources.Length - 1).Name)
End
If
End
Sub
Private
Sub
btnLEdit_Click(
ByVal
sender
As
System.
Object
, _
ByVal
e
As
System.EventArgs) _
Handles
btnLEdit.Click
' Make sure the user has selected an entry.
If
lstLocal.SelectedIndex = -1
Then
MessageBox.Show(
"Select an entry to edit."
)
Return
End
If
' Create a new form for editing the data.
Dim
EditItem
As
New
frmAddEdit(
"Edit Local Resource"
,
"&Edit"
)
EditItem.IsEdit =
True
' Make sure there is data to edit.
If
CurrentSettings.LocalUris
Is
Nothing
Then
MessageBox.Show(
"No Records to Edit"
)
Return
Else
' Provide the records and choose the one to edit.
EditItem.Resources = CurrentSettings.LocalUris
EditItem.RecordNumber = lstLocal.SelectedIndex
End
If
' If the user changes the data, update the settings
' database and show changes on screen.
If
EditItem.ShowDialog(
Me
) = DialogResult.OK
Then
CurrentSettings.LocalUris = EditItem.Resources
GrabAPictureSettings.SaveSettings(CurrentSettings)
lstLocal.Items(lstLocal.SelectedIndex) = _
EditItem.Resources(lstLocal.SelectedIndex).Name
End
If
End
Sub
Private
Sub
btnLDelete_Click(
ByVal
sender
As
System.
Object
, _
ByVal
e
As
System.EventArgs) _
Handles
btnLDelete.Click
' Make sure the user has selected an entry.
If
lstLocal.SelectedIndex = -1
Then
MessageBox.Show(
"Select an entry to remove."
)
Return
End
If
' Create a temporary record array.
Dim
Temp(CurrentSettings.LocalUris.Length - 2)
As
LocalUri
' Remove the requested record.
Dim
Count
As
Int32 = 0
For
Each
Item
As
LocalUri
In
CurrentSettings.LocalUris
' Add the record if it doesn't match the target.
If
Not
Item.Name = lstLocal.Items(lstLocal.SelectedIndex)
Then
Temp(Count) = Item
Count += 1
End
If
Next
' Update the settings.
CurrentSettings.LocalUris = Temp
GrabAPictureSettings.SaveSettings(CurrentSettings)
' Update the display.
lstLocal.Items.RemoveAt(lstLocal.SelectedIndex)
End
Sub
Private
Sub
btnLSelect_Click(
ByVal
sender
As
System.
Object
, _
ByVal
e
As
System.EventArgs) _
Handles
btnLSelect.Click
' Wallpaper manipulation class.
Dim
Wallpaper
As
New
WinWallpaper
' Choose the wallpaper style.
Select
Case
CurrentSettings.LocalUris(lstLocal.SelectedIndex).Style
Case
WinWallpaper.Styles.Stretched
Wallpaper.Style = WinWallpaper.Styles.Stretched
Case
WinWallpaper.Styles.Centered
Wallpaper.Style = WinWallpaper.Styles.Centered
Case
WinWallpaper.Styles.Tiled
Wallpaper.Style = WinWallpaper.Styles.Tiled
End
Select
' Create a wallpaper URI.
Dim
NewUri
As
New
Uri( _
CurrentSettings.LocalUris(lstLocal.SelectedIndex).Location)
' Set the wallpaper location.
Wallpaper.WallpaperURI = NewUri
End
Sub
Let’s look at each of these event handlers in turn. The btnLAdd_Click() event handler is the simplest of the group. It begins by creating a new frmAddEdit using the default constructor. When there are local resources to provide in CurrentSettings.LocalUris, the program supplies them to the AddItem.Resources property. At this point, the application displays the dialog box. If the user clicks Add, rather than Cancel, in the Add Local Resource dialog box (which produces a return value of DialogResult.OK), the application obtains the updated list of resources from AddItem.Resources and places them in CurrentSettings.LocalUris. The application then saves the database by calling GrabAPictureSettings.SaveSettings() with CurrentSettings. Finally, the application displays the newly added item in the Local Sources list.
The btnLEdit_Click() event handler begins by checking whether the user has actually selected an entry to edit by checking lstLocal.SelectedIndex (a value of -1 indicates no selection). If not, the application displays an error message and exits. It then creates a new frmAddEdit() using a special constructor that allows modification of the title bar text and the btnAddEdit.Text property, so that the resulting dialog box is completely customized. You’ll find that there are actually four constructors for frmAddEdit:
- No modification
- Modify the title
- Modify both title and btnAddEdit.Text property
- Modify both title and btnAddEdit.Text property in a remote source setting
Providing this sort of customization reduces the work you need to do and yet provides a better interface for the user. The next step is to set the EditItem.IsEdit property to True, which tells frmAddEdit to fill the fields with data to edit, rather than present a blank form. Again, this is the type of customization that will actually save you time later. (A second property, EditItem.IsRemote, determines whether the data should come from the local or remote wallpaper database—the default is to use the local database.)
The application has to make two decisions when editing a record. First, it has to check whether there is a record to edit. If there aren’t any records, the application displays a dialog box stating as much and exits. Second, it must determine which record to edit. The code passes the value in lstLocal.SelectedIndex onto EditItem.RecordNumber. As the application is currently configured, the contents of lstLocal must precisely match the contents of CurrentRecords, which means that lstLocal remains unsorted. A future update will make it possible to sort the list, if desired, but for now, the application is designed for simplicity of understanding, rather than aesthetic appeal. The remainder of the btnLEdit_Click() code works just like the btnLAdd_Click() event handler, with the result that any changes are immediately saved to the database.
Deleting a record means checking for the required record in the database by name and then removing that particular record. The btnLDelete_Click() event handler begins by checking whether the user has actually selected a record (lstLocal.SelectedIndex must equal a value other than -1). It then creates a temporary array, Temp, of type LocalUri, that will hold one record less than the current number of records. The next bit of code may look confusing at first, but all it really does is move all of the records in CurrentSettings.LocalUris that don’t have the name of the selected record as defined by lstLocal.Items(lstLocal.SelectedIndex) to Temp. The result is Temp has one less record than CurrentSettings.LocalUris when the process is finished. The code then copies the new list of records from Temp to CurrentSettings.LocalUris and saves the result to disk. The final step is to remove the name from the Local Sources list.
Selecting a specific local source is relatively straightforward. The btnLSelect_Click() event handler begins by creating Wallpaper, which is type WinWallpaper. It’s important to remember that modifying the Wallpaper object automatically changes the Desktop wallpaper. You saw how this works in the previous post and it works the same here. The application relies on the index provided by the user’s selection, lstLocal.SelectedIndex, to select the correct wallpaper in CurrentSettings.LocalUris. The application then sets the wallpaper style and provides it with a location in the form of a Uri object, NewUri. The result is that the user sees the selected wallpaper on screen.
Manage Remote Database Resources
The code for managing the remote database resources is almost precisely the same as the code for managing local database resources. In fact, the modifications are mainly cosmetic, such as changes to the frmAddEdit title and button text. However, there are a few distinct differences to note as shown here.
Private
Sub
btnRAdd_Click(
ByVal
sender
As
System.
Object
, _
ByVal
e
As
System.EventArgs) _
Handles
btnRAdd.Click
' Create a form to add the record.
Dim
AddItem
As
New
frmAddEdit(
"Add Remote Resource"
,
"&Add"
,
True
)
' Set the resources when available.
If
Not
CurrentSettings.RemoteUris
Is
Nothing
Then
AddItem.RemoteSources = CurrentSettings.RemoteUris
End
If
' If the user makes changes, add the information to
' the settings database and display it on screen.
If
AddItem.ShowDialog(
Me
) = DialogResult.OK
Then
CurrentSettings.RemoteUris = AddItem.RemoteSources
GrabAPictureSettings.SaveSettings(CurrentSettings)
lstRemote.Items.Add( _
AddItem.RemoteSources(AddItem.RemoteSources.Length - 1).Name)
End
If
End
Sub
Private
Sub
btnEdit_Click(
ByVal
sender
As
System.
Object
, _
ByVal
e
As
System.EventArgs) _
Handles
btnEdit.Click
' Make sure the user has selected an entry.
If
lstRemote.SelectedIndex = -1
Then
MessageBox.Show(
"Select an entry to edit."
)
Return
End
If
' Create a new form for editing the data.
Dim
EditItem
As
New
frmAddEdit(
"Edit Remote Resource"
,
"&Edit"
,
True
)
EditItem.IsEdit =
True
' Make sure there is data to edit.
If
CurrentSettings.RemoteUris
Is
Nothing
Then
MessageBox.Show(
"No Records to Edit"
)
Return
Else
' Provide the records and choose the one to edit.
EditItem.RemoteSources = CurrentSettings.RemoteUris
EditItem.RecordNumber = lstRemote.SelectedIndex
End
If
' If the user changes the data, update the settings
' database and show changes on screen.
If
EditItem.ShowDialog(
Me
) = DialogResult.OK
Then
CurrentSettings.RemoteUris = EditItem.RemoteSources
GrabAPictureSettings.SaveSettings(CurrentSettings)
lstRemote.Items(lstRemote.SelectedIndex) = _
EditItem.RemoteSources(lstRemote.SelectedIndex).Name
End
If
End
Sub
Private
Sub
btnRDelete_Click(
ByVal
sender
As
System.
Object
, _
ByVal
e
As
System.EventArgs) _
Handles
btnRDelete.Click
' Make sure the user has selected an entry.
If
lstRemote.SelectedIndex = -1
Then
MessageBox.Show(
"Select an entry to remove."
)
Return
End
If
' Create a temporary record array.
Dim
Temp(CurrentSettings.RemoteUris.Length - 2)
As
RemoteUri
' Remove the requested record.
Dim
Count
As
Int32 = 0
For
Each
Item
As
RemoteUri
In
CurrentSettings.RemoteUris
' Add the record if it doesn't match the target.
If
Not
Item.Name = lstRemote.Items(lstRemote.SelectedIndex)
Then
Temp(Count) = Item
Count += 1
End
If
Next
' Update the settings.
CurrentSettings.RemoteUris = Temp
GrabAPictureSettings.SaveSettings(CurrentSettings)
' Update the display.
lstRemote.Items.RemoveAt(lstRemote.SelectedIndex)
End
Sub
Private
Sub
btnSelect_Click(
ByVal
sender
As
System.
Object
, _
ByVal
e
As
System.EventArgs) _
Handles
btnSelect.Click
' Wallpaper manipulation class.
Dim
Wallpaper
As
New
WinWallpaper
' Choose the wallpaper style.
Select
Case
CurrentSettings.RemoteUris(lstRemote.SelectedIndex).Style
Case
WinWallpaper.Styles.Stretched
Wallpaper.Style = WinWallpaper.Styles.Stretched
Case
WinWallpaper.Styles.Centered
Wallpaper.Style = WinWallpaper.Styles.Centered
Case
WinWallpaper.Styles.Tiled
Wallpaper.Style = WinWallpaper.Styles.Tiled
End
Select
' Create a wallpaper URI.
Dim
NewUri
As
New
Uri( _
CurrentSettings.RemoteUris(lstRemote.SelectedIndex).Location)
' Set the wallpaper location.
Wallpaper.WallpaperURI = NewUri
End
Sub
Of course, everything is done using CurrentSettings.RemoteUris in this case because you’re working with the remote settings. In addition, every one of the dialog boxes uses the most complex frmAddEdit constructor, which configures the application for a remote source. I’ll leave it to you to explore this code based on the conversation of the local source workings.
Well, that’s it for frmConfigure. The next post will complete the basic application. We’ll look at how frmAddEdit works. In the meantime, feel free to contact me about any questions at John@JohnMuellerBooks.com. I’ll also start entertaining some additions to this basic application. I have a few in mind, but I’d love to hear your thoughts on the subject. You can find the last post in this series at: Exploring the GrabAPicture Application (Part 12).