by Wojciech Sura

Theme-aware resources in Windows Phone

Windows Phone supports two themes: light and dark. Since UI in this ecosystem is quite… say, minimalistic, the first theme can be described as “black on white” and the second as “white on black”.

The most common way to design appearance of your application is to use predefined resources, which are provided by the system. For instance, to create text in a frame with default theme colors, write:

[xml]<Border Margin="4" BorderBrush="{ThemeResource PhoneForegroundBrush}"
BorderThickness="{ThemeResource ButtonBorderThemeThickness}"
Background="{ThemeResource PhoneBackgroundBrush}">
<TextBlock Foreground="{ThemeResource PhoneForegroundBrush}"
FontSize="{ThemeResource TextStyleExtraLargePlusFontSize}">Themed manually</TextBlock>
</Border>[/xml]

The border will match current theme color:

lightdark

But what if you want to introduce your own styles to application, but still match current theme?

The solution is to create different ResourceDictionary objects for light and dark scheme and then to import them in special way to your page:

[xml]<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light" Source="Light.xaml" />
<ResourceDictionary x:Key="Dark" Source="Dark.xaml" />
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Page.Resources>[/xml]

The phone will now choose appropriate resource file, depending on current theme. Remember to use ThemeResource instead of StaticResource though, such that when theme changes all relevant values will be reloaded from appropriate ResourceDictionary.

by Wojciech Sura

Event-to-command in Windows Phone

During writing my Windows Phone application I ran into a problem: I wanted the button to behave differently, depending on whether user tapped it or pressed-and-held.

Most XAML controls provide a Holding event, which occurs when user keeps touching an item – so the solution seems to be as simple as implementing an event.

But that doesn’t look nice in XAML – most actions can be implemented declaratively – as bindings to commands in the viewmodel. Implementation of event in code-behind seems like a code smell in this beautiful MVVM environment.

There’s a solution though – to use Behaviors SDK.

First of all, add Behaviors SDK (XAML) to your project references – you may find it among few assemblies, which Microsoft provides as optional ones for Windows Phone applications.

Then – as usual – you’ll have to define XML namespaces for two additional C# namespaces:

[xml]<Page

xmlns:i="using:Microsoft.Xaml.Interactivity"
xmlns:icore="using:Microsoft.Xaml.Interactions.Core">[/xml]

Finally, you may add a behavior and action to the button:

[xml]<Button Command="{Binding TapCommand}">
<i:Interaction.Behaviors>
<icore:EventTriggerBehavior EventName="Holding">
<icore:InvokeCommandAction Command="{Binding HoldingCommand}" />
</icore:EventTriggerBehavior>
</i:Interaction.Behaviors>
Press or hold me
</Button>[/xml]

Remember though, that after HoldingCommand, the TapCommand will fire as well. Make sure to implement it properly.

by Andreas

Silverlight 4 Default button

Silverlight har ikke den innebygde Default button propertien som støttes i for eksempel Panels i ASP.NET. For de utviklerne som lever et liv i skyggen sørger denne for at du kan peke på en control innenfor et panel hvor Click event skal kalles når brukeren trykker Enter. Et typisk eksempel er en login-side hvor Enter simulerer trykk på Log in-knappen.

Silverlight / XAML har ikke denne muligheten – merkelig nok. Det er derfor en del fremgangsmåter rundt på nettet, men denne her er grei og fungerer i Silverlight 4.

Denne koden er frekt og freidig (og sikkert uten samtykke) lånt av Patrick Cauldwell – men siden jeg gir ham cred så er det sikkert greit.

1. Opprett en klasse i prosjektet, kall denne DefaultButtonService

2. Kopier inn dette (oppdater namespace til ditt eget):


using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;

namespace SilverlightDemo
{
public static class DefaultButtonService
{
public static readonly DependencyProperty DefaultButtonProperty =
DependencyProperty.RegisterAttached(“DefaultButton”, typeof(string), typeof(DefaultButtonService), new PropertyMetadata(OnDefaultButtonChanged));

public static string GetDefaultButton(DependencyObject d)
{
return (string)d.GetValue(DefaultButtonProperty);
}

///
/// Sets the CommandParameter property.
///

public static void SetDefaultButton(DependencyObject d, string value)
{
d.SetValue(DefaultButtonProperty, value);
}

private static void OnDefaultButtonChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TextBox tb = d as TextBox;
if (tb != null)
{
tb.KeyUp += new KeyEventHandler(tb_KeyUp);
}
}

static void tb_KeyUp(object sender, KeyEventArgs e)
{
switch (e.Key)
{
case Key.Enter:
string name = (string)((DependencyObject)sender).GetValue(DefaultButtonProperty);
object root = App.Current.RootVisual;
object button = ((FrameworkElement)root).FindName(name);
if (button is Button)
{
ButtonAutomationPeer peer = new ButtonAutomationPeer((Button)button);

IInvokeProvider ip = (IInvokeProvider)peer;
ip.Invoke();
}
break;
}
}
}
}

3. Legg til et xmlns i XAML:

xmlns:my=”clr-namespace:SilverlightDemo”

4. Legg til en attributt på alle controls som skal trigge at knappen “btnDemo” skal trykkes, for eksempel en textbox: