Implement Settings Popup Pages for Windows Store Apps

Preface

No, this is not the first sample to be found in the internet on this topic. Anyway, I decided to add another one because the two I was looking at (see links below) gave good ideas, but did not satisfied me at all.

Changes to App.xaml.cs

To begin, new items need to be added to the settings charm somehow. I did this by changing the app.xaml.cs. This is my starting point here.

First thing is to add a new using statement:

using Windows.UI.ApplicationSettings

Next, we need to know when to add our items to the settings charm. The class SettingPane has an event called CommandsRequested, which “… occurs when the user opens the settings pane. Listening for this event lets the app initialize the setting commands and pause its UI until the user closes the pane.” (description copied from MSDN docs).

So I added an event handler as the last statement of the App.OnLaunched method.

SettingsPane.GetForCurrentView().CommandsRequested 
  += OnSettingsCommandsRequested;

The handling method OnSettingsCommandsRequested is implemented in this sample like this:

private void OnSettingsCommandsRequested
  (
  SettingsPane settingsPane,
  SettingsPaneCommandsRequestedEventArgs args
  )
{
  args.Request.ApplicationCommands
    .Add(new SettingsCommand("about", "About", OnSettingsInvoked));

  args.Request.ApplicationCommands
    .Add(new SettingsCommand("popupHeaderBackgroundSlidesIn", 
     "Background slides in", OnSettingsInvoked));

  args.Request.ApplicationCommands
    .Add(new SettingsCommand("popupHeaderWithoutTransition", 
     "Header without transition", OnSettingsInvoked));

  args.Request.ApplicationCommands
    .Add(new SettingsCommand("popupHeaderWithTransition", 
     "Header with transition", OnSettingsInvoked));
}

As you can see, no matter which command is selected by the user, the method OnSettingsInvoked is called. Because the SettingsCommand constructor takes a settingsCommandId as first parameter, I am able to distinguish between the actions to be taken inside OnSettingsInvoked. Of course, one can also implement different handlers for each new command. I decided to us a single one in this sample because the action to be taken is very similar.

private void OnSettingsInvoked
  (
  IUICommand command
  )
{
  // Get the command id.
  string commandId = command.Id as string;

  // Has to be set, otherwise return.
  if (commandId == null)
  {
    return;
  }

  switch (commandId)
  {
    case "about":
      OpenSettingsPage<AboutPage>();
      break;
    case "popupHeaderBackgroundSlidesIn":
      OpenSettingsPage<HeaderBackgroundSlidesInPage>();
      break;
    case "popupHeaderWithoutTransition":
      OpenSettingsPage<HeaderWithoutTransitionPage>();
      break;
    case "popupHeaderWithTransition":
      OpenSettingsPage<HeaderWithTransitionPage>();
      break;
    default:
      break;

  }
}

The magic of opening a settings popup page is encapsulated by the method OpenSettingsPage<TPage>. It takes a type parameter to know what kind of popup page should be created. The type needs to be derived from SettingsPageBase to make sure the correct kind of page will be opened.

private void OpenSettingsPage()
  where TPage : SettingsPageBase, new()
{
  SettingsPopup = new Popup();

  SettingsPopup.IsLightDismissEnabled = true;
  SettingsPopup.Width = App.SettingsPopupWidth;
  SettingsPopup.Height = Window.Current.Bounds.Height;

  // Add the proper animation for the panel.
  SettingsPopup.ChildTransitions = new TransitionCollection();
  SettingsPopup.ChildTransitions.Add(new PaneThemeTransition()
  {
    Edge = (SettingsPane.Edge == SettingsEdgeLocation.Right) ?
           EdgeTransitionLocation.Right :
           EdgeTransitionLocation.Left
  });

  // Create a SettingsFlyout the same dimenssions as the Popup.
  TPage settingsFlyout = new TPage();
  settingsFlyout.Width = SettingsPopup.Width;
  settingsFlyout.Height = SettingsPopup.Height;

  // Place the SettingsFlyout inside our Popup window.
  SettingsPopup.Child = settingsFlyout;

  // define the location of our Popup.
  SettingsPopup.SetValue(Canvas.LeftProperty, 
    SettingsPane.Edge == SettingsEdgeLocation.Right 
    ? (Window.Current.Bounds.Width - SettingsPopup.Width) 
      : 0);
  SettingsPopup.SetValue(Canvas.TopProperty, 0);
  SettingsPopup.IsOpen = true;
}

It is worth to mention that SettingsPopup is a property of the App class. When implementing my first settings pages, I made this a local variable. But whenever I clicked somewhere into the main window while the settings page was open, my app crashes. I was not able to debug the problem. Even no UnhandledException handler helped me out.

SettingsPageBase

To avoid copy & paste development for the back button click handler, I created a base class for the settings pages. This is the class SettingsPageBase, located in the Common folder. The handler’s task is to close the Popup and re-open the settings charm when the back button is pressed.

protected virtual void OnGoBack
  (
  object sender,
  RoutedEventArgs args
  )
{
  // First close our Popup.
  Popup parent = this.Parent as Popup;

  if (parent != null)
  {
    parent.IsOpen = false;
  }

  // If the app is not snapped, then the back button shows the Settings pane again.
  if (ApplicationView.Value != ApplicationViewState.Snapped)
  {
    SettingsPane.Show();
  }
}

Mastering the Transition

When you open up the settings charm of this sample app, you will notice three different settings items: “Background slides in”, “Header without transition”, and “Header with transition”. You might ask why this. The answer is, that these are the three kinds of transitions I noticed when I was starting with settings pages. And it took me a while to figure out why my first attempts did not look the way I expected it (Header with transition).

Background slides in

When you open the “Background slides in” page, look at how the header block behaves, especially the background. It slides in, together with the button, text and logo. So when the page pops in, there is a tiny block on the left where the background color is the page’s background, not to the header’s.

The header controls slide in as expected, together with the content of the page, but that did not satisfied me. So I dig into the samples, because they did not behave that way. There, I found the next version:

Header without transition

On this page, the background of the header is set correctly. No slide in. But also, no slide in of the button, text, and image. Their position is fixed in relation to the upper left corner even when the page opens, while the describing text slides in. So still not satisfied (and not comply with the UX requirements).

Header with transition

This is the way I like it. The background is not sliding, while the header’s controls do, together with the page’s content.

To get this done, I had to change different things. When you find an easier way, I would be happy if you post it in a comment.

First, the root element of the page must not contain any Transitions definition. So no child element will slide in by default.

The settings pages consists of a Grid having two rows. One for the header, one for the content.

I put two Grids into the header row. The first, without transition, to have the background be in place when the page pops in. The second, containing the back button, text, and image, with a transition definition:

<Style x:Key="SettingsHeaderContentStyle" TargetType="Grid">
  <Setter Property="Transitions">
    <Setter.Value>
      <TransitionCollection>
        <EntranceThemeTransition/>
      </TransitionCollection>
    </Setter.Value>
  </Setter>
</Style>

This makes sure only the content of the header will slide in.

And because the root element of the page does not contain any transition definitions, also the content part, which is a StackPanel in the second row of the main Grid in my sample, needs the same transition definition.

All application-specific styles can be found in Common/ApplicationStyles.xaml.

UX Design Requirements

This app satisfies the following UX design requirements (all copied from Windows 8 User experience guidelines):

  • Place your settings Flyout on the same side of the screen as the charms. The charms and the settings window may be on the left side of the screen if the system’s text direction is right-to-left (like Arabic).
  • Settings Flyouts should be narrow (346 pixels) or wide (646 pixels).
  • Settings Flyouts should have a header that includes a back button, the name of the entry point that opened the Flyout, and the app’s icon (small one, 30x30px).
  • Use a light-dismiss surface, so that the settings Flyout disappears when the user touches anywhere on the screen outside of the surface.

The Dev Center sample “Settings Flyout” names a few more requirements, which I was not able to find in the guidelines. But they all seem reasonable, so I will list them here too:

  • Height has to be 100% of the screen.
  • Header is 80px high.
  • Header’s background must match the start tile’s background (from the manifest).
  • Flyout’s border must be darker than the header’s background (80% of its value). For instance, the background color in the example below is #999999, so the boarder color is rgb(0.8 * #99, 0.8 * #99, 0.8 * #99), which is rounded to #797979a.
  • The background of the main content area must be white. This can cause a problem if your app requests the dark theme; the text foreground color is white in the dark them, which renders it invisible when the background color is white. To request the light theme, set RequestedTheme="Light" in the app.xaml.
  • Both of the header’s and content’s controls must be animated.

The Sample Code

can be found here. To build an run the sample, you need Windows 8 and Visual Studio 2012.

Sample Screenshot

Links

Guidelines for app settings (Windows Store apps)

Store apps UX Guidelines Index

Dev Center Settings Flyout sample

Dev Center App settings sample (Windows 8)

Microsoft Advertising Services AdControl Transition in XAML/C#

Preface

According to the documentation, AdControls are hosted in a WebView control. For some reasons I was not able to figure out, WebView controls do not slide in when a page loads (or pop in, whatever the correct wording is). This means that your AdControl will not slide in neither.

Now imagine the following: You have created a great page including an AdControl. When the page is opened, all content slides in, except the AdControl. Would you like that? I do not.

Make AdControls Sliding

For all who are familiar with transitions and storyboards in XAML, this won’t bring much or any news. For those who are not, like I was when using AdControls the first time, this might help save some time.

The key is to add a Storyboard to the page containing the AdControl. And luckily, there is a predefined ThemeAnimation to do the pop in: the PopInThemeAnimation. Here is a sample:

<Page.Resources>
  <Storyboard x:Name="PopInStoryboard">
    <PopInThemeAnimation 
        Storyboard.TargetName="AdControlPanel728x90" 
        FromHorizontalOffset="120" 
        SpeedRatio=".3"/>
  </Storyboard>
</Page.Resources>

The Storyboard.TargetName is the name of the control to animate. In case you use the AdControl configuration presented in the post Configure Microsoft Advertising Services’ AdControl using XAML/C#, make sure that you assign the name to the dynamically created AdControl. The class AdControlContainingPage of the sample takes care of it.

The FromHorizontalOffset “… sets the distance by which the target is translated in the horizontal direction when the animation is active” (description copied from MSDN online docs). Unfortunately, the docs don’t say what the reference point is. So you have to play around a little bit to make sure the AdControl slides in the same distances as the other controls do. In my sample, it was almost the left margin of topmost panel – but only almost, not always.

The SpeedRatio is “… a finite value greater than 0 that specifies the rate at which time progresses for this timeline, relative to the speed of the timeline’s parent. If this timeline is a root timeline, specifies the default timeline speed. The value is expressed as a factor where 1 represents normal speed, 2 is double speed, 0.5 is half speed, and so on.” (description copied from MSDN online docs). In my experience, the value of 0.3 makes the AdControl slide in as fast as the other controls.

Adding the storyboard is only on half of the work. The other part is to make the storyboard run.

// Run storyboard if one exists.
Storyboard storyboard = FindName("PopInStoryboard") as Storyboard;

if (storyboard != null)
{
  storyboard.Begin();
}

I put this code sniped into the LoadState method of my AdControlContainingPage base class, which is derived from LayoutAwarePage. LoadState is called when the page is about to be displayed. I think this is a good place to start transitions.

The AdControlContainingPage is the base class of all pages containing AdControls. So I just have to define the StoryBoard in the XAML, and I am done 🙂

Links

The AdControl animation is part of the sample code of the post Configure Microsoft Advertising Services’ AdControl using XAML/C#, where you can download the code.

Configure Microsoft Advertising Services’ AdControl using XAML/C#

Preface

The Microsoft Advertising SDK for Windows 8 allows developers to show ads in their apps. When you look at the walkthrough for putting ads in an app using XAML/C#, you can see that you have to set the ApplicationId and AdUnitId property of each AdControl control in your app.

For testing purposes, Microsoft has defined the ApplicationId d25517cb-12d4-4699-8bdc-52040c712cab and several AdUnitIds (can be found on the Test Mode Values page). These values are required in case you have no ids created in the pubCenter for yourself or in case you want to test your app in the emulator. (Well, on my machine the emulator showed productive ads even though the docs says it does not.)

Since I do not want to change my app every time I switch between the emulator and my dev machine, I was looking for a way to make these setting configurable.

Where to Store the Configuration Data?

In common .NET applications, the answer to this question is very simple: put it in the app.config. Unfortunately, for Windows Store apps the app.config approach is not available, or at least not offered by .NET for Windows Store apps.

So I built my own app.config mimic. Please have a look at the post Mimic app.config in Windows Store Apps for further details.

How to Change the Values During Runtime?

My first try was to define the AdControls in the XAML file and change both ApplicationId and AdUnitId in the constructor of the page’s class right after the call to PageClass.InitializeComponent. After receiving “NoAdAvailable” errors (which shows how important it is to implement an error event handler for AdControls), I had a look at the documentation.

In the remarks to the AdUnitId property the docs says that “This property can be set only when the AdControl is instantiated using the default constructor. Once set, this property cannot be modified.” The ApplicationId can be changed whenever you want. But that won’t help, because ApplicationId and AdUnitId are strongly tied together. Means, an AdUnitId is only valid in conjunction with its corresponding ApplicationId.

This means I cannot change the AdUnitId of all the AdControls that are defined in the XAML. Bad news? Not that bad – because we can also create UI controls during runtime, not only in XAML!

The AdControl Replacement Approach

After playing around a little bit I was choosing a replacement approach. This means that I define AdControls in XAML, and replace them during page initialization with those AdControls having the correct values for Application- and AdUnitId.

I prefer this approach because it offers the ability to check the look of the page also during design time, not only at runtime. So it is much easier to see if the page looks good. This requires me to set the (matching) height and width of the AdControls properly both in the XAML and configuration.

There is one prerequisite to use the replacement approach the way I implemented it: the AdControl to be replaced has to be a child control of a Panel (or derived class). Otherwise it is not possible to put the new AdControl at the place where the old one was.

The definition of the required config values is encapsulated by the class AdControlConfigData. The class looks like this:

public class AdControlConfigData
{
  [XmlAttribute]
  public string AdControlName { get; set; }

  [XmlAttribute]
  public string AdUnitId { get; set; }

  [XmlAttribute]
  public double Height { get; set; }

  [XmlAttribute]
  public double Width { get; set; }
}

The corresponding serialized data in the app.config looks like this:

<AdControlConfigData AdControlName="AdControl300x600" 
  AdUnitId="10043030" Width="300" Height="600"/>

The value of the ApplicationId is not part of this container. It is defined as a simple and single value in the app.config, since it is the same for all AdControls.

Replace the AdControls

In the sample code, I created a class called AdControlContainingPage, which is derived from LayoutAwarePage. This class is the base class of all pages containing AdControls. It holds all the functionality required to replace them, plus a basic handler for AdControl errors.

The XML config data is read by the ConfigurationManager class introduced in the Mimic app.config in Windows Store Apps post, also the XmlDeserialize used later.

For the sample app, the content of the app.config looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<!-- Configuration settings for Debug Build -->
<configuration>
  <appSettings>
    <!-- Use Microsoft Advertising Services Test ApplicationId -->
    <add key="AdApplicationId" 
            value="d25517cb-12d4-4699-8bdc-52040c712cab"/>
  </appSettings>

  <AdControlConfigList300x600>
    <AdControlConfigData AdControlName="AdControl300x600" 
          AdUnitId="10043030" Width="300" Height="600"/>
  </AdControlConfigList300x600>

  <AdControlConfigList300x250>
    <AdControlConfigData AdControlName="AdControl300x250" 
          AdUnitId="10043056" Width="300" Height="250"/>
  </AdControlConfigList300x250>

  <AdControlConfigListMultiple>
    <AdControlConfigData AdControlName="AdControl160x600" 
          AdUnitId="10043136" Width="160" Height="600"/>
    <AdControlConfigData AdControlName="AdControl728x90" 
          AdUnitId="10042998" Width="728" Height="90"/>
  </AdControlConfigListMultiple>
</configuration>

The different AdControlConfigData entities are extracted by the method AdControlContainingPage.GetAdControlConfiguration, which is shown here:

private static List<AdControlConfigData> GetAdControlConfiguration
  (
  XmlDocument xmlConfig,
  string sectionName
  )
{
  List<AdControlConfigData> configDataList 
    = new List<AdControlConfigData>();

  XmlNodeList xmlConfigDataList 
    = xmlConfig.DocumentElement
      .SelectNodes(
        String.Format("./{0}/AdControlConfigData", sectionName));

  foreach (IXmlNode node in xmlConfigDataList)
  {
    AdControlConfigData configData 
     = XmlDeserializer.Deserialize<AdControlConfigData>(node);

    configDataList.Add(configData);
  }

  return (configDataList);
}

Now that we have the configuration settings as a list of objects, which is really easy to handle, we can go on to replace the controls. This is done by AdControlContainingPage.ReplaceAdControls.

private void ReplaceAdControls
  (
  List<AdControlConfigData> adControlConfigDataList,
  string adApplicationId
  )
{
  // iterate over the list of configured AdControls.
  foreach (AdControlConfigData configData in adControlConfigDataList)
  {
    // Find the AdControl to be replaced.
    AdControl oldAdControl 
      = FindName(configData.AdControlName) as AdControl;

    // If the oldAdControl is not found, we can't replace it. So try the next one.
    if (oldAdControl == null)
    {
      Debug.WriteLine(String.Format("AdControl name >{0}< not found", configData.AdControlName));
      continue;
    }

    // Get the parent of the adcontrol. Needs to be a kind of panel.
    Panel parent = oldAdControl.Parent as Panel;

    // If the parent is not a panel, try the next one.
    if (parent == null)
    {
      Debug.WriteLine(String.Format("AdControl name >{0}< is not placed inside a panel or derived class. AdControl cannot be replaced.",
        configData.AdControlName));
      continue;
    }

    // Keep the position of the old AdControl.
    int postion = parent.Children.IndexOf(oldAdControl);

    // and remove it
    parent.Children.RemoveAt(postion);

    // Create the new AdControl with the correct ApplicationId and AdUnitId.
    AdControl adControl = new AdControl()
    {
      ApplicationId = adApplicationId,
      AdUnitId = configData.AdUnitId, // From msdn: This property can be set only when the AdControl is instantiated. Once set, this property cannot be modified.
      HorizontalAlignment = HorizontalAlignment.Left,
      Height = configData.Height,
      IsAutoRefreshEnabled = true,
      VerticalAlignment = VerticalAlignment.Top,
      Width = configData.Width
    };

    // Add the error hander
    adControl.ErrorOccurred += OnAdControlErrorOccurred;

    // Add the new control to the parent at the correct position.
    parent.Children.Insert(postion, adControl);
  }
}

The orchestration of these activities is done by AdControlContainingPage.SetupAdControls, which looks as follows:

protected async void SetupAdControls
  (
  string configSectionName
  )
{
  try
  {
    // Load the app.config.
    XmlDocument xmlConfig = await ConfigurationManager.GetConfig();

    // Get the AdApplicationId
    string adApplicationId 
      = ConfigurationManager
        .GetAppSettingsValue(xmlConfig, "AdApplicationId");

    // Extract the AdControl config data from the XML into a object list.
    List<AdControlConfigData> adControlConfigDataList 
      = AdControlContainingPage
        .GetAdControlConfiguration(xmlConfig, configSectionName);

    // Replace the AdControls
    ReplaceAdControls(adControlConfigDataList, adApplicationId);
  }
  catch (Exception e)
  {
    Debug.WriteLine(String.Format("Exception occurred:{0}{1}", 
      Environment.NewLine, e));
  }
}

One should call AdControlContainingPage.SetupAdControls right after the call of InitializeComponent of the derived class. In the sample, the derived classes are SamplePage300x250, SamplePage300x600, and SamplePageMultiple, which can be found in the SubPages folder of the solution.

The Sample Code

can be found here. To build and run the sample, you need to have the Microsoft Advertising SDK for Windows 8 installed. Have fun 🙂

Load It From The Windows Store

A slightly extented version of the sample can also be found in the Windows Store.

And finally, some screenshots of the sample app.

Main Page

Sample Page

Sample Page

Sample Page

Mimic app.config in Windows Store Apps

Preface

I know, the concept of app.config files is not part of Windows Store App development. The docs and postings say that one should use local or roaming settings.

But I needed something to pass environment depending initial data to the app. One scenario I can think of is the URI of a web service that is consumed by an app. This URI might defer from development environment to test to production in case you develop both the app and the service. Changing the code or using conditional directive (#if) might not be the best idea to implement that.

appSettings Approach

The approach copies the appSettings part of .NET app.config usage. Just add an XML file to the project and make sure the “Build Action” property of the file is set to “Content”. This file will be included into the deployment package and can be accessed during runtime.

The content of this file might look like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="MyConfigSetting" value="The Config Value"/>
  </appSettings>
</configuration>

Since app.config is not part of the Windows Store app concept, there is no ConfigurationManager class to ease the access. But it is not that hard to read and parse XML files.

In my approach, I implemented the loading of the XML file in two steps: get the file and load it.

StorageFile file = await StorageFile
.GetFileFromApplicationUriAsync(
 new Uri(String.Format("ms-appx:///Assets/Configuration/{0}",
   ConfigManager.ConfigFileName)));

XmlDocument xmlConfiguration 
= await XmlDocument.LoadFromFileAsync(configFile);

As you can see from the URI, I put the config file into the Assets/Confioguration folder. The name is dynamic to give me the chance to use different files for different environments. I will come back to this later.

If you know the Windows.Data.Xml.Dom.XmlDocument class you might ask why I am not using the XmlDocument.LoadFromUriAsync method. The answer is simple: it did not work right away (using the same URI), and I was too lazy to search for the reason.

Now that the XML is loaded, it is easy to read the values:

IXmlNode node 
= xmlConfiguration.DocumentElement
 .SelectSingleNode(
  "./appSettings/add[@key='MyConfigSetting']/@value");

if (node == null)
{
  // do some error handling or set default value
  return;
}

string configValue = (string) node.NodeValue;

And that’s it. One might want to encapsulate this functionality by a class, implementing additional error handling, and so forth.

Complex Configuration Data using XML Serialization

In .NET client applications, one can use sections to handle complex configuration data that does not fit into key / value pairs. Of course, even for .NET client applications there is a good chance you have to write the section handler yourself.

For Windows Store apps, it is sure you have to write the handling of complex configuration data yourself. But you don’t have write loads of XML readings. Why? Because you can use XML serialization, like in .NET applications. The System.Xml.Serialization.XmlSerializer is available for Windows Store apps too 🙂 Well, at least almost. Not all members available in .NET are available for Windows Store apps. But it became a lot easier to deserialize objects from XML without namespace qualification. (More about this issue for .NET can be found here: http://stackoverflow.com/questions/870293/can-i-make-xmlserializer-ignore-the-namespace-on-deserialization). There is no helper needed any more (at leats for Windows Store apps).

So what have I done? I created a container class for the complex configuration data. This class might look like this (comments omitted):

public class ComplexConfigData
{
  [XmlAttribute]
  public string StringValue { get; set; }

  [XmlAttribute]
  public double DoubleValue { get; set; }

  [XmlAttribute]
  public int IntValue { get; set; }
}

I am using the XmlAttribute attribute to keep the XML compact. The config file with additional complex data looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="MyConfigSetting" value="The Config Value"/>
  </appSettings>

  <ComplexConfigDataList>
    <ComplexConfigData StringValue='StringValue1' DoubleValue='1.1' IntValue='10'/>
    <ComplexConfigData StringValue='StringValue2' DoubleValue='2.2' IntValue='20'/>
  </ComplexConfigDataList>
</configuration>

Here is how all the (manually) serialized ComplexConfigData objects are retrieved from the XML:

XmlNodeList configDataList 
= xmlConfiguration.DocumentElement
 .SelectNodes(
  "./ComplexConfigDataList/ComplexConfigData");

foreach (IXmlNode node in configDataList)
{
  ComplexConfigData configData 
  = XmlDeserializer.Deserialize<ComplexConfigData>(node);
  // do something with configData
}

The deserialization is encapsulated by this generic method in my class XmlDeserializer:

public static T Deserialize<T>
  (
    IXmlNode serializedObject
  )
  where T : class
{
  return (
    new XmlSerializer(typeof(T))
    .Deserialize(
      new StringReader(
       serializedObject.GetXml())) as T);
}

Selecting the Correct File

Above, where the URI is built to get the config file, a placeholder and a property is used. The property is defined as follows:

private const string ConfigFileName
#if DEBUG
  = "Config.Debug.xml";
#else
  = "Config.Release.xml";
#endif // DEBUG

The reason to use the conditional directive (#if) is that I do not want to change the code in case I have different settings for debug (development) and release (production). This approach does not fit for three different environments, but it is a starting point. Of course, you can change the content of the config file whenever you need. But this is more error prone than selecting the wrong build configuration. (The Windows Store only accepts release builds, so this approach will pick the release settings when the app is installed via Windows Store.)

Sample Variation

With version 3.0 of the source code, the sample implementation is not exactly what is described here. For demonstration purposes I thought it would be nice to be able to switch the app.config that is used via the Settings charm.

This means, the name of the app.config file loaded does not depend on the build configuration, but on app configuration values. You can switch it directly. The change is reflected immediately by the UI controls.

As said, this is for demonstration purposes. I do not think that this approach (giving the user the ability to switch the app.config) will be very useful in real world scenarios. But for this sample I think it is.

In case you want to use the app.config mimic in your app, the code to couple the app.config to the build configuration is still included in the sample. See Configuration.ConfigurationManager.

Considerations

Think twice if you really need this. Don’t use it just because you are used to it from .NET applications.

If you have the need to save configuration data during runtime, the app.config mimic is not the right approach to me. Better use local or roaming application data then (see links below).

Load It From The Windows Store

A slightly extented version of the sample can be found in the Windows Store.

Finally

… have fun 🙂

You can find the sample code here.

History

2013-08-13: Source code update V3.0.0.1
Instance Factory Logo changed; typo fixed.

2013-08-09: Source code update V3.0
Select the app.config file via Settings Charm, independend from build configuration.

2013-07-23: Source code update V2.1
Minor design changes (logo & splash screen).

2013-07-10: Source code update V2.0
UI completely redesigned.

Sample Screenshot

Sample Screenshot

Links

Local application data (Windows Store apps using C#/VB/C++ and XAML)

Roaming application data (Windows Store apps using C#/VB/C++ and XAML)

How to load file resources (Windows Store apps using C#/VB/C++ and XAML)

Guidelines for app settings (Windows Store apps)

Implement Settings Popup Pages for Windows Store Apps sample

Telerik RagGridView – Where Are My Cells Gone?

My latest application required a RadGridView having a dynamic number of columns. And therefor, the binding of the data an event handler needed to by managed during runtime as well.

Not really in issue: handle the RowLoaded event, iterate over the cells of the row passed by the event arguments, and everything is fine. That’s what I thought and implemented.

It was fine until the number of rows to be displayed exceeded the number of rows that could be displayed. When starting to scroll the grid in the UI, an exception occurred (in this case, the browser windows turned white and the status bar mentioned there was an error on the page – really helpful!)

So I had to start the debugger, and immediately I saw what caused the exception: the number of cells in the row passed to the event handler was smaller than the number of columns of the grid. Since I iterated over the number of columns of the grid, and then used the index to access the corresponding cell of the row, it has to fail.

Soon it was obvious that the number of cells in the row matched the number of columns displayed in the browser. But where have all the other cells gone? The answer to this question is UI Virtualization, explained in this article: http://www.telerik.com/help/wpf/radgridview-features-ui-virtualization.html.

After reading the article, the solution was quite easy: turn of the column virtualization of the grid, and the number of cells in the row passed to the handler was matching to the number of columns of the grid.

I think it’s worth to mention that during the initial loading of the grid, all rows had the matching number of cells in the RowLoaded-handler, even with UI virtualization turned on. The mismatch only occurred when the user started to scroll.

Silverlight, Telerik GridView, Dynamically Created Loaded Handler & Performance

I like Silverlight, Telerik’s GridView control and the ability to create the columns of a grid dynamically.

Recently, I had to build up a grid during runtime. The number of columns and the header text is unknown at design time (read it from the database), but nothing to worry about. The XAML file only contains the definition of the Telerik grid control itself, but no column definitions.

Almost every column should contain a checkbox. And I need to handle the load event of every dynamically created checkox. Since I had to use Silverlight 4, I needed to create the cell template by using the XamlReader loading a XAML fragment.

To verify that the creation of the grid columns works at all, I did not include the load event handling in the XAML fragment for the first try. The application started, the grid and its columns were built as expected. Everything was fine.

Then I added the event handler to the fragment . The result contains something like this: <CheckBox Loaded="MyCheckBoxLoadedHandlerMethod"/>.

Having this little change done, opening the view containing the grid hangs in that way, that after a while IE complained the localhost was not responding any more. CPU usage went up, and memory consumption too.

What I think what happened is, that for each checkbox in the grid (in my sample 17 lines by 14 checkbox columns), an event handler instance is created either by Silverlight or the Telerik control. This seems to be such resource intensive, that it brought down IE.

Now what I had to do is to create a single event handler instance and assign it to every newly created checkbox. But how can I do that in Silverlight 4? In Silverlight 4 you cannot assign an object to a DataTemplate, except using the XamlReader approach (Silverlight 5 offers this ability).

I added a RowLoaded event handler to the grid. The handler iterates thru the cells of the row and looks for the checkbox child element. If it finds one, the one-and-only handler is assigned to the Click event.

It still takes time to show up the view, but now it works. I can’t tell what the real reason for the slowdown of the first approach is. But I found a way to get it running 🙂

Limitations of Private Accessors and Generic Methods (JIT Compiler Encountered an Internal Limitation)

Private accessors are really helpful for extensive unit testing. But they do have their limitations.

I wrote a generic protected method having a declaration like this:

protected ReturnType MyMethod<T>(OneClass, DateTime, DateTime, Func<OtherClass, T>, out List<T>);

Calling this method via an accessor in my unit test, I ran into an exception complaining “JIT Compiler encountered an internal limitation”.

First, I thought it was a LINQ issue, because I used LINQ inside to retrieve some data from a list, using the delegate passed. But I was wrong. Debugging into the test, the exception was thrown at the moment the method was called.

When I changed the declaration to

protected ReturnType MyMethod<T>(OneClass, DateTime, DateTime, Func<OtherClass, T>, out List<SomeType>);

the test finished successfully. But I had not implemented a generic method to be limited to the type of the resulting list.

Soon, the accessor got into suspicion. When I declared the generic version of the method as public, and used an instance of the implementing class, the test was successful too.

The solution in my case was to keep the method protected, derive a mock class from the implementing class in my test project, and use an instance of that derived class by the test.

Silverlight Printing and Inheritance of Language Settings

From what I learned, printing in Silverlight (4) is straight forward: Create a control and print it.

I used this pattern in a Silverlight application I built. Because I had to implement some multipage- and list handling, I created user controls that I added into a stack panel of the main print control during runtime (inside of the PrintDocument.PrintPage event handler).

To get the correct – current UI culture dependent – formatting of all of the date and numeric values when printed, I set the Language property in the ctor of the main print control to the current culture’s language. But when the child controls were printed, the culture-dependent output was formatted in en-US style, not in the current culture style. I had to set the Language property inside of each child control.

Of course, at the time the child control was created using new ChildControl, the Language property could not be set to the value of the parent, since at that time the child did not know it has one. But I expected Silverlight to change the Language property to the parent’s value as soon as the child as added to the Children collection.

Well, adding Language = XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.Name) ; into each child control’s ctor (or into the base class’ ctor), wasn’t that hard to do 😉

Generic UserControl Base Class in Silverlight

Having generics in .NET is a great thing. I already loved template classes in C++, missed them in .NET 1.x, and was happy to get a (little bit restricted) kind of templates in .NET 2.0.

Building a Silverlight application, I felt the need to create a generic UserControl base class. But I was unable to use it until I found the following hint: “Known Issue – Controls Deriving From A Generic Base Class Must Be In Separate Assembly” (http://blogs.msdn.com/b/wpfsldesigner/archive/2010/01/22/known-issue-controls-deriving-from-a-generic-base-class-must-be-in-separate-assembly.aspx).

This article mainly describes generic UserControl classes for WPF, and at the end puts the focus on the issue in Silverlight. And it gives the crucial hint: One has to create a “middle” class. The only purpose of the middle class is to create a non-generic type based on the generic base class. The declaration looks like this:

MiddleClass : GenericBaseClass<TypeClass>

where GenericBaseClass<T> itself is derived from UserControl.

The base class can be abstract. The middle class of course have to override all abstract methods. I only put a throw (new NotImpementedException("NeedsToBeOverridden")) into the implementation of these methods to remind me not to forget to override them by the derived class (the user control itself).

The user control now can be derived from the middle class, which does not require type parameters. Silverligt’s XAML parser is happy, and I am too. The declaration looks like this:

DerivedClass : MiddleClass

Simple, isn’t it?!

The reason why Silverlight requires this workaround is a lack of the x:TypeArguments property in the XAML.

Silverlight’s DatePicker and Telerik’s RadWindow Dialog

In my current Silverlight project, I’m using the DatePicker control, which is part of the Silverlight SDK.

In one scenario, the DatePicker with TwoWay binding is embedded into a User Control, which itself is embedded into another User Control. The format is “dd.MM.yyyy”. Entering e.g. 23.11.2011 works fine, means the value of the bound property is set to the 23rd of November in 2011.

Then I needed a date input inside of a modal dialog. Shouldn’t be a problem, so I just copied and pasted the XAML from the User Control into the dialog’s XAML. But entering 23.11.2011 in the dialog, the bound property remains null. First I thought there was a binding issue at all, but after some playing around I noticed that entering 8.11.2011 worked fine. The bound property was set correctly to the 8th of November 2011. But as soon as the entered day was bigger than 12 – the maximum value of a month – the input was ignored.

Luckily, I already had a DateConverter created in that project. This converter parses the entered string in the ConvertBack method using the current culture. So I bound the DatePicker control to that converter too, set a breakpoint at the ConvertBack method, and stepped into it. And to my surprise, the entered values was interpreted and bound correctly now.

To me, the behavior does not make sense. Why does the Date Picker control act different in these two scenarios? One thing might be that the RadWindow as the parent somehow changes the culture. But from my understanding, this should lead to the 11th of August 2011 when entering 8.11.2011.

At least I’m happy that I found a workaround. I do not have to understand everything at all…