In-app File Management Changes in Windows 8.1 and Visual Studio 2013

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:

  1. StorageLibrary
  2. GetParentAsync
  3. IsEqual
  4. TryGetItemAsync
  5. NeighboringFilesQuery
  6. Windows Index
  7. Direct Draw Surface
  8. 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.

Our design
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.

StorageLibrary, AddFolder
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.

Loaded Library Folders
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.

Prompt for Library Folder removal
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.

Parent Folder
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:

SearchBox
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:

SearchBox 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!

Hannes DuPreez
Hannes DuPreez
Ockert J. du Preez is a passionate coder and always willing to learn. He has written hundreds of developer articles over the years detailing his programming quests and adventures. He has written the following books: Visual Studio 2019 In-Depth (BpB Publications) JavaScript for Gurus (BpB Publications) He was the Technical Editor for Professional C++, 5th Edition (Wiley) He was a Microsoft Most Valuable Professional for .NET (2008–2017).

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read