Sunday, September 8, 2013

Reading Text from an embedded file in a WinRT application

When you want to provide data to a WinRT application (a.k.a. Windows Store App) it is sometimes useful to embed a file in your application package. This file may for instance contain help information, initial user settings, sample data...

To do that you need
  1. to include the file in the project
  2. to read the data
Let's make an example using a text file.
To include the text file in the application, just add the text file to the solution

Note that I have created a folder to put my text files .This avoid cluttering the project with too many files.

It is important to correctly select the build action Content to ensure that the file shall effectively be embedded in the application file.

Now that the file is included in the application package we must get access to it.
The code below shows how to read the whole text file and display its first two lines in textblocks
        protected async override void OnNavigatedTo(NavigationEventArgs e)
            //retrieve the text file content
            Uri uri = new Uri("ms-appx:///MyTextFiles/MyTextFile1.txt");
            StorageFile file =
                await StorageFile.GetFileFromApplicationUriAsync(uri);
            IList<String> lines = await FileIO.ReadLinesAsync(file);

            //use the retrieved data
            TextBlock1.Text = lines[0];
            TextBlock2.Text = lines[1];

Note the usage of an URI instead of a path to identify the file. Embedded files cannot be accessed using a file path.

Note also the very strange URI syntax with a triple slash ms-appx:///

Obviously, the same technique can be used to embed other things than text files. You could embed images, sounds or binary data.
I hope this will help you the next time you need to embed a data file inside a Windows store application.

Thursday, May 23, 2013

Preventing the winrt combox to jump around when it is opened

The combox in windows 8 (winrt) XAML has a bad tendency to jump around when the user opens it.
See the example below:

 <ComboBox  HorizontalAlignment="Center" VerticalAlignment="Center"
    Grid.RowSpan="2" Grid.ColumnSpan="2" SelectedIndex="0" >    
            <TextBlock Text="first"/>                             
            <TextBlock Text="second"/>                          
            <TextBlock Text="Third"/>                           
            <TextBlock Text="Very long text................." />

When the combobox is closed it is well centered on the cross But when it becomes open it is not centered at all.

Note this does not occur when the combobox alignment is set to stretch but this is not always a solution that fits with your XAML layout.

Vertically the opened combobox is arranged so that the selected line is at right place. That's OK but the horizontal movement is (I think) awful for the user.

The best way that I have found to avoid it is to force a MinWidth value that is large enough to display the longest text that shall have to be displayed in the combobox. This is a bit a dirty trick but it works nicely.

 <ComboBox  HorizontalAlignment="Center" VerticalAlignment="Center"      
  Grid.RowSpan="2" Grid.ColumnSpan="2" SelectedIndex="0" MinWidth="200">
            <TextBlock Text="first"/>                                 
            <TextBlock Text="second"/>                                  
            <TextBlock Text="Third"/>                               
            <TextBlock Text="Very long text................." />     

With this modification we get:

The opened combobox stays horizontally centered on at the correct position.