Introduction
Welcome to today’s article! Today I have an exciting task (and the pleasure) of covering the new File Management objects in Windows 8.1 and Visual Studio 2013. A lot of new funky features have finally been added and it will surely make your file management tasks much easier! Let me start.
New File Management Objects in Windows 8.1 and Visual Studio 2013
The following is a list of new file management capabilities added in Windows 8.1:
- StorageLibrary
- GetParentAsync
- IsEqual
- TryGetItemAsync
- NeighboringFilesQuery
- Windows Index
- Direct Draw Surface
- Block Compression
I will explain all of these with a little project. Let’s play!
Our Project
Open Visual Studio 2013 and start a new Windows Store project named Files_Example, and design your page to resemble Figure 1.
Figure 1 – Our design
The resulting XAML code:
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="In-App File Management with VB and Windows 8.1" VerticalAlignment="Top" FontSize="36" Margin="281,60,0,0"/> <Button x_Name="btCreatFolder" Content="Create New Folder" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="237,154,0,0"/> <Button x_Name="btRemoveFolder" Content="Remove Folder" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="1057,230,0,0"/> <Button x_Name="btParentFolder" Content="Get Parent Folder" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="430,154,0,0"/> <Button x_Name="btIsEqual" Content="IsEqual" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="252,296,0,0"/> <Button x_Name="btKnownFolders" Content="Known Folders" HorizontalAlignment="Left" VerticalAlignment="Top" RenderTransformOrigin="8.134,4.988" Margin="643,164,0,0"/> <ComboBox x_Name="cbFolders" DisplayMemberPath="DisplayName" HorizontalAlignment="Left" VerticalAlignment="Top" Width="183" Margin="1029,166,0,0"> </ComboBox> <Button x_Name="btLoadFolders" Content="Load All Folders" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="861,164,0,0"/> <ListBox x_Name="lstKnownFolders" Margin="646,209,521,400"/> <TextBlock x_Name="tbParent" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Parent Will Show Here" VerticalAlignment="Top" Margin="426,209,0,0" FontSize="22"/> <TextBlock x_Name="tbIsEqual" HorizontalAlignment="Left" TextWrapping="Wrap" Text="IsEqual Result Will Be Displayed Here" VerticalAlignment="Top" Margin="255,348,0,0" FontSize="16"/> <SearchBox x_Name="sbSearch" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="93,446,0,0" PlaceholderText="Enter Search Phrase Here" /> <TextBlock x_Name="tbSearch" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Margin="378,459,0,0" FontSize="22"/>
You can use your own names, or stick with the names I have given. Let’s now concentrate on the StorageLibrary class.
StorageLibrary Class
Windows 8.1 Preview introduces the new StorageLibrary class. This class allows users to manage folders within their own personal libraries. This means that users can add their own folders into their Videos folder or Music folder. This would have been very useful with my Wallpaper article I wrote a month or so back. I like having things organized in their own folder, and felt limited using only one main folder. Let’s have a closer look:
Add the following namespaces to your project:
Imports Windows.Storage Imports Windows.UI.Popups Imports Windows.ApplicationModel.Search
Create a modular variable so that all the procedures on the page can access it and modify it:
Dim MyPicturesLibrary As StorageLibrary 'Main Library To Use
Adding a Folder to the Library
Double click the Create New Folder button; add the following code behind it:
Private Async Sub btCreatFolder_Click(sender As Object, e As RoutedEventArgs) Handles btCreatFolder.Click 'add permission in app.manifest first!! 'Get Library MyPicturesLibrary = Await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures) 'Add New Folder To It Via FilePicker Dim NewFolder As StorageFolder = Await MyPicturesLibrary.RequestAddFolderAsync() End Sub
Inside the btCreateFolder_Click event, we set the MyPicturesLibrary variable equal to the Pictures Knownfolder. We then, create a new variable, aptly named NewFolder. This object is a StorageFolder and will be the folder the user picks to add. How? Well, the RequestAddFolderAsync method makes use of a FolderPicker for the user to select a folder. Once a selection has been made, the folder will be added to the library. Nice. A screen (similar to Figure 2) pops up and allows you to make a selection.
Figure 2 – StorageLibrary, AddFolder
Removing a Folder from the Library
Removing is a bit more involved. The problem is: we need to find a way for the user to select a folder that he / she would like to remove from the library. Based on this, I have decided to add two controls to the page (do not worry, if you have designed your page to resemble Figure 1, it will already be there!): A Load Folders button, and a ComboBox that will show all the folders in the library. The premise would be to use the Load Folders button to load all the Library folders into a ComboBox. Once these items are loaded, the user can select any folder from the combobox, and it will remove that selected folder from the library. Add the next code behind the btLoadFolders button:
Private Async Sub btLoadFolders_Click(sender As Object, e As RoutedEventArgs) Handles btLoadFolders.Click 'Load all folders into combobox MyPicturesLibrary = Await StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures) ' Bind the ComboBox to the list of folders currently in the library cbFolders.ItemsSource = MyPicturesLibrary.Folders 'added DisplayMemberPath="DisplayName" to combo xaml code End Sub
Via the GetLibraryAsync method we obtain all the folders present in the current library. We set the ComboBox’s ItemSource property to the found folders. Just a note here. You have to add DisplayMemberPath=”DisplayName” to the ComboBox’s XAML code. If we do not, we will simply see StorageFolder for each item, instead of each item’s name. Just to recap, here is the XAML code for the ComboBox:
<ComboBox x_Name="cbFolders" DisplayMemberPath="DisplayName" HorizontalAlignment="Left" VerticalAlignment="Top" Width="183" Margin="1029,166,0,0"> </ComboBox>
If you were to run this app, and click Load Folders, your screen would resemble Figure 3.
Figure 3 – Loaded Library Folders
Now we can proceed to the Remove Folder’s event. Add the following code:
Private Async Sub btRemoveFolder_Click(sender As Object, e As RoutedEventArgs) Handles btRemoveFolder.Click 'Get Selected Combo Box Folder Dim FolderToRemove = DirectCast(cbFolders.SelectedItem, StorageFolder) 'Remove Selected Folder From Library Await MyPicturesLibrary.RequestRemoveFolderAsync(FolderToRemove) End Sub
A user made a selection, based on this the RequestRemoveFolderAsync method will prompt to remove the selected folder from the library as shown in Figure 4.
Figure 4 – Prompt for Library Folder removal
This wraps up the new StorageLibrary Class in this article. Let us proceed to getting a folder’s parent folder.
GetParentAsync Method
With the new GetParentAsync method, you can get the parent StorageFolder of any file or any folder. A Parent folder, as its name implies is the Folder containing the subfolder we are looking for. Again, this would have been very useful with Windows 8! Add the next code behind the btParentFolder button:
Private Async Sub btParentFolder_Click(sender As Object, e As RoutedEventArgs) Handles btParentFolder.Click 'get parent folder 'CameraRoll KnownFolder Dim MyCameraRollFolder As StorageFolder = KnownFolders.CameraRoll 'Determine CameraRoll's Parent Folder Dim ParentFolder As StorageFolder = Await MyCameraRollFolder.GetParentAsync() 'Show In TextBox tbParent.Text = ParentFolder.Name End Sub
We create an object named MyCameraRollFolder and specify that it is a KnownFolder. I will elaborate more on this later in this article. We then use the GetParentAsync method to obtain the library folder’s parent (Pictures) and display it inside a textbox named tbParent.
Figure 5 – Parent Folder
IsEqual Method
The new IsEqual method can be used to determine if two storage files or folders represent the same file or folder, meaning they are equal. Let us play with it a bit. Add this code behind the IsEqual button:
Private Sub btIsEqual_Click(sender As Object, e As RoutedEventArgs) Handles btIsEqual.Click 'test if folders are equal 'CameraRoll KnownFolder Dim MyCameraRollFolder As StorageFolder = KnownFolders.CameraRoll 'PlayList KnownFolder Dim MyPlayListFolder As StorageFolder = KnownFolders.Playlists 'Determine If Both Folders Are The Same Dim SameFolder = MyCameraRollFolder.IsEqual(MyPlayListFolder) 'Display Result tbIsEqual.Text = SameFolder End Sub
We create two StorageFolder objects, then we make use of the IsEqual method to determine if the folders are the same folder. Obviously this is a very small example, the real use would perhaps be more complicated. I am just demonstrating how to use it. The result would be False in this case because these folders are not the same.
SearchBox
An exciting new tool that has been included in Visual Studio 2013 for Windows 8.1 is the new SearchBox control. This makes content searching in an app very very easy. Let us have a look at it. I don’t know if you might recall when I asked you to create all the objects on your page as per Figure 1, you might have seen a strange control. If you looked at the XAML code, you would have seen the SearchBox was added. It looks like this:
Figure 6 – SearchBox
The XAML code looks like:
<SearchBox x_Name="sbSearch" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="93,446,0,0" PlaceholderText="Enter Search Phrase Here" /> <TextBlock x_Name="tbSearch" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Margin="378,459,0,0" FontSize="22"/>
The TextBox underneath the SearchBox will be use to display the result of the search, as you will see shortly. Let’s add the following modular array to our code:
'Search Suggestions Dim arrSuggestions() As String = {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"}
This is simply our Search Suggestions that will be given as we type a search query into the SearchBox. Add the following procedures:
Private Sub sbSearch_QuerySubmitted(sender As SearchBox, args As SearchBoxQuerySubmittedEventArgs) Handles sbSearch.QuerySubmitted 'Show Entered Text tbSearch.Text = args.QueryText End Sub Private Sub sbSearch_SuggestionsRequested(sender As SearchBox, args As SearchBoxSuggestionsRequestedEventArgs) Handles sbSearch.SuggestionsRequested 'Search Query String Dim strQuery As String = args.QueryText 'If Not Empty If Not String.IsNullOrEmpty(strQuery) Then 'Suggestions To Give Dim colSuggestions As SearchSuggestionCollection = args.Request.SearchSuggestionCollection 'Compare Each Array Item With Entered Text For Each strSuggestion As String In arrSuggestions 'If Suggestions Starts With Entered String If strSuggestion.StartsWith(strQuery, StringComparison.CurrentCultureIgnoreCase) Then 'Add To Suggestion Collection colSuggestions.AppendQuerySuggestion(strSuggestion) End If Next End If If args.Request.SearchSuggestionCollection.Size > 0 Then tbSearch.Text = "Suggestions provided for query: " + strQuery Else tbSearch.Text = "No suggestions provided for query: " + strQuery End If End Sub
Everything happens in the SuggestionsRequested event. It checks what was entered. Then, it loops through the Suggestions array to see if any of the array items start with the phrase entered. If a macth is found it adds this result to its Suggestions collection, which is ultimately used by the SearchBox to display the results. This what it looks like in action:
Figure 7 – SearchBox in action
Indexing
We are now able to index our files or properties via the new Windows.Storage.Search API. What does that mean? Well, indexing files means that it will be searched faster. This increases the performance of your application greatly.
TryGetItemAsync Method
TryGetItemAsync forms part of the StorageFolder class. It in essence does the same as GetItemAsync, but it has built-in error handling capabilities. This means when this method fails, a runtime error will not be generated. Get a magnifying glass so that we can have a closer look at it.
NeighboringFilesQuery Property
As the name implies, the new NeighboringFilesQuery property in Windows 8.1 allows navigation and access to neigboring files (files that also reside in the same folder). Needless to say that this was long overdue (again); let us have a closer look at it:
File Management Objects Updates
KnownFolders
CameraRoll and Playlists have been added to the KnowFolders locations. Here is a small example. Add the following code behind the KnownFolders button:
Private Async Sub btKnownFolders_Click(sender As Object, e As RoutedEventArgs) Handles btKnownFolders.Click 'Open cameraroll and playlists 'CameRoll KnownFolder Dim MyCameraRollFolder As StorageFolder = KnownFolders.CameraRoll 'PlayList KnownFolder Dim MyPlayListFolder As StorageFolder = KnownFolders.Playlists 'Get Folders' Files Dim CameraRollList As IReadOnlyList(Of IStorageItem) = Await MyCameraRollFolder.GetItemsAsync Dim PlayListList As IReadOnlyList(Of IStorageItem) = Await MyPlayListFolder.GetItemsAsync lstKnownFolders.Items.Add("Camera Roll Files") 'Add CameraRoll Folder Contents For Each CameraFile In CameraRollList If TypeOf CameraFile Is StorageFile Then lstKnownFolders.Items.Add(CameraFile.Name) End If Next lstKnownFolders.Items.Add("Play List Files") 'Add PlayList Folder Contents To ListBox For Each PlayFile In PlayListList If TypeOf PlayFile Is StorageFile Then lstKnownFolders.Items.Add(PlayFile.Name) End If Next End Sub
Here, we simply list all the files present inside the CameraRoll and the PlayLists KnownFolders.
FilePicker
The Windows 8.1 FilePicker has been updated to allow split-screen apps and full-screen apps to call it. This means that users will be able to multitask, and they won’t be hindered by a full-screen file picker that they cannot get rid of otherwise.
SkyDrive
You can now make SkyDrive your default storage location and manage SkyDrive directly from Windows 8.1.
Conclusion
This concludes today’s article. I sincerely hope that you have enjoyed the article and that you have learned something interesting today. Until next time, cheers!