Showing posts with label winrt. Show all posts
Showing posts with label winrt. Show all posts

Sunday, February 16, 2014

How to avoid the Exception "A cycle occurred while laying out the GUI." in a Windows store APP


The Observed Problem

Sometimes the exception "A cycle occurred while laying out the GUI." occurs in Windows 8 store application in an unpredicatble way. This can be very frustrating especially when the problem is observed only on some computers and not on others .

Note that when this occurs on a released and deployed Application the Application terminates silently without indicating any error message.

The explanation

The reason for this exception is in fact very simple: as the description says, we have an endless loop in the layout of the GUI. I have found that this nearly always occurs in the SizeChanged event handler.

  
 border.SizeChanged += _SizeChanged;  
 

What can be puzzling is that this can occur even if the SizeChanged Handler does something that should not trigger any endless loop. Example

  
 private  void _SizeChanged(object sender,
                     Windows.UI.Xaml.SizeChangedEventArgs e)
        {
            if (e.NewSize.Width < 150)
            {
                (border.Child as TextBlock).FontSize = 40;   
            }
            else
            {
                (border.Child as TextBlock).FontSize = 80;   
            }
        }
    }
 

Theoretically, the above code should never trigger an endless loop. But this is not the case. For some graphic résolutions, this method triggers endless calls to the _SizeChanged event Handler.

The work around

There is a simple way to make sure that the SizeChanged event is not called endlessly: ignore the event when it is called for nothing. Detecting useless SizeChanged events can easily be done by comparing the old size and the new size; if they are identical then the SizeChanged event was called for nothing and it can safely be ignored.

 
 if (e.PreviousSize != e.NewSize)   
 

Example: to prevent any risk of endless loop we should update the the following code to make it look like this:

  
 private  void _SizeChanged(object sender, 
                     Windows.UI.Xaml.SizeChangedEventArgs e)
        {
            if (e.PreviousSize != e.NewSize)
            {
                if (e.NewSize.Width < 150)
                {
                    (border.Child as TextBlock).FontSize = 40;   
                }
                else
                {
                    (border.Child as TextBlock).FontSize = 80;   
                }
            }
        }

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................." />
        </ComboBox>                                                 


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................." />     
        </ComboBox>                                                      


With this modification we get:


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