Theme-aware XAML resources in a WP7 project - xaml

I'm making a Windows Phone 7 application and I'm a bit confused with dark/light themes.
With a panorama, you very often set a background image. The issue is it's very hard to make a picture which is right for both dark and light themes. How are we supposed to proceed?
Is there a way to force a dark/light theme for a panorama? This will avoid making theme-specific panorama background pictures. Then how do I do? I found xaml files in C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.0\Design. If this is a right way to proceed, how can I import them for my panorama?
Or if there's no way (or if it's wrong) to force a dark/light theme: how to write conditional XAML to set correct resources? Now I have the following XAML (default.xaml) which is fine with the dark theme:
<ImageBrush x:Key="PageBackground" ImageSource="Resources/PageBackground.png" Stretch="None" />
<ImageBrush x:Key="PanoramaBackground" ImageSource="Resources/PanoramaBackground.png" Stretch="None" />
But when I use a light theme, black controls and black texts are hard to read with my dark background pictures. So I made different pictures that I can use this way:
<ImageBrush x:Key="PageBackground" ImageSource="Resources/PageBackgroundLight.png" Stretch="None" />
<ImageBrush x:Key="PanoramaBackground" ImageSource="Resources/PanoramaBackgroundLight.png" Stretch="None" />
Now my issue is to make XAML conditional to declare the right thing depending on the current theme.
I found no relevant way on the Internet. I would prefer not to use code or code-behind for that because I believe XAML is able to do this (I just don't know how).
EDIT: Code snippet to load a xaml file as ResourceDictionary
string xaml = null;
StreamResourceInfo xamlInfo = Application.GetResourceStream(new Uri("light.xaml", UriKind.Relative));
using (StreamReader sr = new StreamReader(xamlInfo.Stream))
xaml = sr.ReadToEnd();
dic = (ResourceDictionary)XamlReader.Load(xaml);
this.Resources.MergedDictionaries.Add(dic);

To force a dark or white theme you can indeed use the styles defined in the folder you pointed out. Copy and Paste the rules you need to your App.xaml (just PhoneForegroundColor, PhoneBackgroundColor and the related Brushes would be a good start).
It's probably better though to stay "theme-aware" and load a different image for light and dark themes. Here is an article explaining how to do this: http://blog.jayway.com/2010/12/16/theme-aware-panorama-background-in-windows-phone-7/

There is another possibility I've found: You can use the Coding4Fun Toolkit Converter according to these instructions. However, I'm unable to use correctly use them.
Another possibiliy is to use an OpacityMask. But this only works for black/white images :/
Yousef's solution looks interesting. but it takes too much time to load. The image will be changed round about 1s after the app started. I've tested this on a Nokia 820. I've moved the call for setting the DataContext in a Loaded Event, which was called much later. Now the call takes place in the constructor, so the image will be already set when the application displays it. However, it still adds more loading time :( Any suggestions on how to improve this?

Related

How to bind an event to a command in a Universal App using the MVVM pattern?

I hope somebody can help.
I've spent some time researching the best way to bind an event to a ViewModel command using the MVVM pattern when developing a Universal App. I'm using MVVM Light.
As a test I'm using the SelectionChanged event of a ComboBox.
I've read a few people that have pinched the Behaviours SDK from the Windows 8.1 / WinRT framework and had some success with that. I have also included the Universal App behaviours SDK in my project and tried the following (put together from Windows 8.1 examples but using the UWP SDK).
XAML
<Page
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core" />
...
<ComboBox ItemsSource="{Binding InputQuantities}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="SelectionChanged">
<core:InvokeCommandAction Command="{Binding SomeComboBoxCommand}" CommandParameter="Foo" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</ComboBox>
View Model
public RelayCommand SomeComboBoxCommand {get; set;}
However, the core:InvokeCommandAction isnt part of the Behaviours SDK and i get Invalid Type: expected type is 'Microsoft.Xaml.Interactivity.ActionCollection'. I've tried to use an ActionCollection.... but I'm not sure I know what I'm doing with that.
Ive successfully got it to work with compiled bindings and using Laurent's Blog Post:
XAML
<ComboBox ItemsSource="{Binding InputQuantities}" SelectionChanged="{x:Bind Vm.SomeComboBoxCommand }" />
View Model
public void SomeComboBoxCommand(object sender, SelectionChangedEventArgs e){//do stuff}
I know this isnt what Laurent is intending to demonstrate here and I think doing this is breaking the decoupling of the view and VM by then having to reference a UI component in my view model to get the selected item. But I've seen references to doing this during my research.
So how can I get this working using The Universal App interaction behaviours, if that's the right way to do it of course?
Update 1.
This is what I attempted to add, believing, incorrectly that I was adding the universal app behaviours SDK. I didn't notice at the time that it was targeting Windows 8.1.
However, my questions still stands: Why wont the InvokeActioncommandwork and why is it throwing the mentioned error? I will look at the other posts as soon as I get to work.
Update 2
After testing this on my works PC (exact same code as above, 1st example and the same behaviours SDK) it works fine and I'm getting the behaviour that I would expect. I need to test again on my home PC to see what has gone wrong. (Thanks to Justin XL for sticking with me)
Update 3
For completeness, after returning home I got the latest version of my project (from being checked in on my works PC) and it now also works on my home PC. I'm not sure what state my Visual Studio was in but it had sufficiently confused me enough to post this question. At least this should serve as a document on how to do what is described in the title. Thanks for all your help.
We seem to be getting this question a lot lately, in several different variants...
I'm not familiar with Universal App but is there any specific reason you're trying to use an event? WPF/Silverlight etc are designed to be data driven, all you need to do is bind the ComboBox's SelectedItem member to a property in your view model and the setter will get called whenever the user selects a new item. Often times you have to do exactly the same processing in response to other parts of your view model changing it (e.g. in Master-Child views) so having that logic in a single place generally makes for a much cleaner architecture.
Check this link: MVVM EventBinding Library ,explains about MVVM EventBinding. This purely decouples the View & View model & pass only the arguements to the command.

External Font Not Loading in Xaml

i tried to load a downloaded font in windows phone app.
i installed the font in pc.
i tried following
<TextBlock Width="237" Text="About" FontSize="36" Height="46" LineHeight="8"
FontFamily="{StaticResource nokia}"/>
<TextBlock Width="237" Text="About"
FontFamily="/font/nokia.ttf#Nokia Cellphone" FontSize="36" Height="46" LineHeight="8"/>
why external font is not loading
It doesn't matter if the font is installed on the PC or not.
For a font to work inside your app you'll need a few things.
You'll have to set the build action to 'Content' and output to directory set to: 'Copy if newer'.
And then the hardest part - Getting the preferred family right. I usually advocate using a tool for it, because the Windows Font viewer does not always show the right one.
'dp font viewer' is the one I usually use.
For a complete guide on implementing custom fonts, you could have a look here: http://www.blendrocks.com/code-blend/2015/01/04/a-complete-guide-to-working-with-custom-fonts-in-your-windows-and-windows-phone-app

How to convert SVG file to XAML in windows 8 / WinRT

How i can convert SVG file to XAML in windows 8 / WinRT. I am new to this XAML / SVG environment. So anyone please help me to implement the same in windows 8. I need to parse this svg file and need to display the content in the page through code.
For me the simplest way to do it is the following:
Open your .svg file in free vector drawing tool Inkscape
Save as "Microsoft XAML (*.xaml)"
Also you may need to update the result output file a bit after conversion, since not all XAML processing engines support converting a string to Figures (as described in the accepted answer to Why does this Xaml Path crash silverlight?). So, for example, if you have this:
<Path Fill="#FFEDEDED" StrokeThickness="1" Stroke="#FFA3A3A3" Opacity="0.7"
VerticalAlignment="Center" HorizontalAlignment="Center" >
<Path.Data>
<PathGeometry Figures="m 1 2 l 4.0525 5.2361 l 4.0527 -5.2361 z "/>
</Path.Data>
</Path>
then you will need to change it to this:
<Path Fill="#FFEDEDED" StrokeThickness="1" Stroke="#FFA3A3A3" Opacity="0.7"
VerticalAlignment="Center" HorizontalAlignment="Center"
Data="m 1 2 l 4.0525 5.2361 l 4.0527 -5.2361 z" />
- OR -
You could use a bit different way to export the xaml from Inkscape, described by Tim Heuer in accepted answer to the question Convert SVG to XAML, because both ways produce different xaml output:
Method (yes, superhack):
Use Inkscape to save as PDF
Rename the Filename extension from PDF to AI
Use Expression Design to open AI document
Export to Silverlight Canvas
UPDATE (2015-08-25)
I've found my self using the second ("hack") way more and more often rather then first (more straightforward) one, because it creates more "expectable" XAML as I would call it.
I cheated and converted my SVG to a font. First, I created the SVG, then using IcoMoon created the font. https://icomoon.io/app/#/select.
I downloaded the font's ttf into my assets folder with content.
Next I add the code. Notice the font filename, then #, then the name of the font. The text should be
<TextBlock Text="" FontFamily="/Assets/icomoon.ttf#icomoon" FontSize="45"</TextBlock>
Please take a look at this article:
Transforming SVG graphics to XAML Metro Icons
You can find here a way to convert via transforming to XPS.
You can use also an Svg2Xaml converter.
There is a free converter available in the Microsoft Store (as standalone Windows application). It is called SVG to UWP XAML Converter.
It worked without any problems converting my multi-color SVGs correctly as batch to XAML, which I added to Visual Studio within a WPF User Control (for a preview you need to select the SVG file manually)

Page Navigation in Windows 8 XAML (without using code behind)

For my windows 8 application i am trying to navigate between pages with out using code behind.
For example, i have one image in my UI without creating tapped event for that image i need to navigate to another page,
<Image Source="ms-appx:///Assets/Logo.png" Width="155" Height="110" Tapped="{ // Navigation method here }"/>
Is it possible to navigate between pages like this...? If possible, how can i get this to work??
XAML is just a declarative language without action part so code behind is an essential part of it.
All interactions work via events and event can be handled in a code behind only. So what you want is not possible with XAML(at least with WinRT XAML).
If you are asking if you can specify the code inside the .xaml file, then no, that is not possible.
If you are asking if you can avoid adding code to the .xaml.cs file, then yes, that is possible. You will still need to specify a method but it can even be done as a simple lambda. You will need to use the Command hooks rather than the Event Hooks, e.g.
<Button Command="{Binding GoConnectionCommand}" ... />
The code for this command is usually defined in the ViewModel as part of the MVVM pattern, and Josh Smith explains it far better than I will.
AlSki mentioned using a ViewModel. Although technically the ViewModel is not part of the "code behind" for the XAML file, it's still code and I believe you were asking for a no code solution.
ixSci is correct that there is no way to do this out of the box without code behind in WinRT XAML.
In full WPF it's possible to do this using a behavior called NavigateToScreenAction. You can read about it here. Unfortunately behaviors don't ship out of the box with WinRT, but they can be added back in by an open source project called WinRtBehaviors.
There is no NavigateToScreenAction behavior for WinRT, but one could be created. There is a good article on creating behaviors with the library here. It will obviously require code to create the behavior, but after it's created you could use it in XAML without any code.
Really, the short answer is it's not possible to navigate without code on WinRT.
Dev support, design support and more awesome goodness on the way: http://bit.ly/winappsupport

Flex 3 loading background color

During loading of a Flex 3 built application, it always shows this blue-grayish background color. I've tried a handful of tips, building preloaders etc, and all that works, but even before the preloaders kick in, that blue-grayish color is displayed. I've tried lots of ways to change it, like editing compiler options, setting background image to an empty string etc, but nothing works.
I had this same issue and spent a good hour looking for a solution. To the best of my understanding, the blueish-grey color is directly set from the HTML file generated from index.template.hmtl. There is a binding in that file under <param name="bgcolor" value="{bgcolor}" /> that sets the background color. I'm assuming that bgcolor should be pulled from the backgroundColor you set in your Application. And you could also just try hard coding your value in that param also.
To get past the default 'bluish' background on loading to say...white, add this to the compiler arguments: -default-background-color #ffffff.