Archive
Fix: XAML – The member Content is not recognized or is not accessible
I was looking into some third-party code, upgrading it from Silverlight 4.x and was getting error ‘The member "Content" is not recognized or is not accessible’ at the following code part:
Looking it up, found that you don’t need to bind the Content property of a ContentPresenter at all if you put it inside the ControlTemplate of a ContentControl (a Button is such too).
Quoting from:
When you put a ContentPresenter in the ControlTemplate of a ContentControl, it automatically displays the Content of the templated control. For example, if you put a ContentPresenter in a ControlTemplate of a Button, the Content property of the ContentPresenter is implicitly bound to the Content of the Button that uses the ControlTemplate.
It is introduced in this MSDN article and have a sample in it, http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter.content(v=vs.95).aspx
HowTo: Clear contents of Silverlight’s RichTextBox control
Was just debugging an issue with loading of saved state at ClipFlair’s Text component, when I realized that Silverlight’s (and WPF’s) RichTextBox control doesn’t accept an empty string at its Xaml proprerty to clear its contents as one would expect. Instead clearing the contents of the RichTextBox requires a call to Blocks.Clear().
In ClipFlair’s case, the Text component (a FloatingWindow descendent) hosts a SilverTextEditor control, which in turn hosts a RichTextBox named rtb and has its own Xaml property, where I added the needed logic to clear the RichTextBox contents when getting a null or empty string. Wonder why Microsoft couldn’t do the same thing.
public string Xaml {
get { return rtb.Xaml; }
set {
if (value != null && value.Trim() != "") rtb.Xaml = value;
else rtb.Blocks.Clear();
} //allows to set null or blank value to clear the RichTextBox
}
HowTo: Bind to a DataContext property named Source in XAML
While refactoring ClipFlair code to use MVVM (Model-View-ViewModel) pattern, I came across the XAML error “Object reference not set to an instance of an object.”, shown in Visual Studio when trying to bind to my ViewModel (accessed implicitly, being set as the DataContext of the XAML control) for a property named Source.
I have settled down to using the following MVVM-style pattern (of my own) at ClipFlair:
Update: Later on, at ClipFlair project, I renamed folder “Views” to “ViewModels” and folder “Components” to “Views” and moved “ViewModels” folder inside the “Views” one to keep view-related stuff in one place.
IImageViewer.cs:
ImageView.cs:
Update: Later on, I refactored this to initialize the fields directly instead of at the constructor:
//can set fields directly here or at the constructor private Uri source = IImageViewerDefaults.DefaultSource;
ImageViewerWindow.xaml.cs (the so-called codebehind for the XAML control):
Note above how we set the “DataContext” of the control to our ViewModel, so that we can bind to its properties implicitly (without referencing it) in the XAML.
Update: There’s something very important I had forgotten to do at the implementation of the “View” property in the code above, that is to listen for PropertyChangeEvents emitted by the ViewModel. In specific, we need to listen for changes of the ViewModel’s “Source” property to keep the View’s “SourceProperty” (a DependencyProperty that is also accessed via the View’s “Source” property) in sync with the ViewModel’s “Source” property. So the code shown in the above screenshot has to be fixed by changing the “View” property’s implementation like below:
For extra safety in case you want to allow setting a null ViewModel to the View property, you could check for (value != null) before trying to add PropertyChanged event handler to it:
if (value != null)
value.PropertyChanged += new PropertyChangedEventHandler(View_PropertyChanged);
Obviously, if more DependencyProperties are added to the component (e.g. to be able to set them declaratively from XAML when instantiating the component) that have to be in sync to respective ones at the ViewModel (which is held by the View property), then the “View_PropertyChanged” method (event handler) implementation has to be extended with “else if” statements for each of those properties to set the respective dependency properties from the matching ViewModel properties.
BTW, if your ViewModel passes null to the changed property name to mark a single change event for multiple properties, then you have to also take that in mind (else you will get exception when you try to call “Equals” method on null string), by doing something like below:
if (e.PropertyName == null) {
Source = View.Source;
OtherProperty = View.OtherProperty;
//…sync all properties since we are not told which ones changed
return;
}
else if (e.PropertyName.Equals(“Source”) {
Source = View.Source;
}
else if (e.PropertyName.Equals(“OtherProperty”)
{
OtherProperty = View.OtherProperty;
}
//…
Note that instead of “.Equals” one could have also used “==” operator, since the C# compiler maps the string equality operator to string’s “.Equals” method.
Update: Another retouch I have since done to the code above is to avoid hardcoding property names and their default values and use nstead ithe proprerty name constants defined at the class IImageViewerProperties and the respective default values defined at IImageViewerDefaults. For example, I prefer to use (after adding a “using ClipFlair.Models.Views;” to the top):
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register(IImageViewerProperties.PropertySource, typeof(Uri), typeof(ImageWindow), new FrameworkPropertyMetadata(
(Uri)IImageViewerDefaults.DefaultSource,
new PropertyChangedCallback(OnSourceChanged)));
Update: I eventually opted for using a “switch” statement instead of nested if / else if statements, to keep things cleaner when more properties are added:
protected void View_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == null) { Source = View.Source; //... } else switch (e.PropertyName) //string equality check in .NET uses ordinal (binary) comparison //semantics by default { case IImageViewerProperties.PropertySource: Source = View.Source; break; //... } }
In an even newer iteration of that code, I removed the if/else and added the null check in the switch statement:
protected void View_PropertyChanged(object sender, PropertyChangedEventArgs e) { switch (e.PropertyName) { case null: Source = View.Source; //... break; case IImageViewerProperties.PropertySource: Source = View.Source; break; //... } }
ImageViewerWindow.xaml (the XAML control):
The issue at the last screenshot is that you can’t write Source=”{Binding Source}” as you’d write Source=”{Binding SomeDataContextProperty}”, but need to write Source=”{Binding Path=Source}” instead, since Source is a keyword at Binding expression syntax.
BTW, note that at the “edImageURL” TextBox I use Mode=TwoWay (two-way binding, the default is one way binding from source [the DataContext in our case] to target), whereas at the Image control I don’t. Both get an image URI from the ViewModel’s “Source” property, but we also want to be able to edit the URI at the textbox and update the view’s Source property (which will in turn update the Image control with the new image).
Also, note that apart from passing a URI to the Source property of an Image control there’s also a more verbose syntax one could use above, which can be handy to know of:
<Image>
<Image.Source>
<BitmapImage UriSource=”{Binding Path=Source}” />
</Image.Source>
</Image>
The <Image.Source> tag here is using the so-called property element syntax pattern. In the snippet above it sets a value to the Source property of the Image tag. XAML can use both XML attributes and child elements to set values to properties of controls, but whereas the attribute name would be “Source”, the child element tag has to be “Image.Source”, not just “Source”, since the XML schema needs to have unique definitions for the XML tags, whereas multiple objects could define different Source properties causing naming collisions.
According to http://10rem.net/blog/2012/03/27/tip-binding-an-image-elements-source-property-to-a-uri-in-winrt-xaml this more verbose syntax is needed at Windows 8 Metro-style apps (that is for the WinRT API) for binding an Image to a URI (but since that article is back from March 2012, probably this is not an issue any more).
Fix: The tag ‘TimeUpDown’ does not exist in XML namespace (Silverlight Toolkit)
If you use TimeUpDown control from Silverlight Toolkit in your XAML like below (copy pasting from CaptionGrid at ClipFlair source):
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<DataTemplate x:Key="StartTimeCellTemplate">
<TextBlock Margin="4" Text="{Binding Begin}" />
</DataTemplate>
<DataTemplate x:Key="StartTimeCellEditTemplate">
<input:TimeUpDown Format="hh:mm:ss"
Value="{Binding Begin, Mode=TwoWay, ValidatesOnExceptions=True, NotifyOnValidationError=true}"
/>
</DataTemplate>
…
</ResourceDictionary>
then even though it seems to not complain in the XAML designer of Visual Studio 2010, then at Build time, even if you’ve added a reference to System.Windows.Controls.Input.Toolkit assembly (the 5.0.5.0 version for the Silverlight 5 Toolkit [December 2011 release]), you get:
The tag ‘TimeUpDown’ does not exist in XML namespace ‘clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit’
Similar bad behaviour occurs if you try to drag-drop the TimeUpDown control from Visual Studio toolbar (assuming you’ve installed the Silverlight Toolkit first) onto the XAML designer, no xml namespace (named xmlns:input above) is added and you just get <TimeUpDown /> in the designer.
The solution is to also add to your project a reference to System.Windows.Controls assembly (be sure to select same version DLL as above [e.g. 5.0.5.0]). For some reason the System.Windows.Controls.Input.Toolkit doesn’t seem to pull that together and must have some internal dependency to it (although the error you get is very cryptic).
Below is the Add Reference dialog of Visual Studio 2010, you either use the “Extensions” from the right handside, or type-in “System.Windows.Controls” at the search box to quickly spot those two assemblies.
Note that If you have a Silverlight assembly project with some UserControl in it and you apply the workaround I mentioned above, then if you use that UserControl in a Silverlight app (in a Page or other UserControl) you get a RUNTIME error this time at launch saying XamlParserError at the title bar and the exception text:
The type ‘TimeUpDown’ was not found because ‘clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit’ is an unknown namespace
This time the fix is to add a reference to "System.Windows.Controls.Input.Toolkit" to the project.
The funny thing is that this project (that uses a library that hosts a control that uses TimeUpDown itself) DOESN’T NEED to have a reference to "System.Windows.Controls", as the library does need to compile.
The other funny thing is that it does compile OK without adding the "System.Windows.Controls.Input.Toolkit" reference, but it shows runtime error.
This issue has been reported for some time now at:
but hasn’t yet been fixed.
Update:
This may also be related:
https://zoomicon.wordpress.com/2012/07/02/fix-the-tag-xxx-does-not-exist-in-xml-namespace-clr-namespaceyyy/
I noticed that when I tried to compile on a machine that didn’t have Silverlight 5 Toolkit, it was eventually trying to use the Silverlight 4 Toolkit version of System.Windows.Control.Input from my Debug folder (not sure how that DLL ended up there, probably was brought in automatically via some other library’s dependencies by Visual Studio). So maybe you end up with multiple assemblies with the same name in the project and you have to remove the old ones.
You may also run into this issue if your solution was using Silverlight 5 Toolkit and you try to build the project on another machine that has Silverlight 4 Toolkit only. Solution is to install Silverlight 5 Toolkit too and then make sure the project refers to the 5.0 version of System.Windows.Controls.Input.Toolkit.dll and that the reference doesn’t have a path that points into your solution but to the program files folder instead, where Silverlight Toolkit gets installed.
How to crash Visual Studio 2010 via (Silverlight) XAML recursion bug
Following up on a note about Visual Studio 2010 crashing at my previous post, this is the XAML that crashes VS2010 when opened up in a Silverlight project:
<UserControl x:Class="SilverlightApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400"><UserControl.Resources>
<ResourceDictionary>
<Style x:Key="MyStyle" TargetType="StackPanel">
<Setter Property="Margin" Value="0,5,0,5" />
</Style>
</ResourceDictionary>
</UserControl.Resources><Grid x:Name="LayoutRoot" Background="White">
<Grid.Resources>
<Style TargetType="StackPanel">
<Setter Property="Style" Value="{StaticResource MyStyle}" /> <!– THIS LINE CRASHES VISUAL STUDIO (EVEN WHEN YOU TRY TO TYPE IT IN) –>
</Style>
</Grid.Resources><StackPanel/>
</Grid>
</UserControl>
This crashes VS2010 upon loading, because it tries to show the XAML page in the designer. I created that XAML in Notepad++ since when I was trying to type the problematic line (marked in the XAML above) it crashed VS2010 immediately before I managed to save.
BTW, you should use the XAML syntax I suggested at my previous post that uses Style inheritance instead (although it would be nice if you could do for any node <X CloneSource=…/> for any XAML node to copy its attributes and values from a same-typed node instance in some resource etc. instead of relying on the node supporting some mechanism like Style does with BasedOn [that is Style Inheritance]).
<Grid.Resources>
<Style TargetType="StackPanel" BasedOn="{StaticResource MyStyle}" />
</Grid.Resources>
Speaking of crashes, VS2010 should be more clever and if it sees a certain file caused a crash (assuming it has info on file being loaded upon or just before crash), the next time of opening the solution it should warn the user against opening that file (to avoid a new crash that stops one from loading the solution).
Note that I tried to open up the XAML file standalone in Visual Studio and it says:
Style object is not allowed to affect the Style property of the object to which it applies.
at System.Windows.Setter.Seal()
at System.Windows.SetterBaseCollection.Seal()
at System.Windows.Style.Seal()
at System.Windows.StyleHelper.UpdateStyleCache(FrameworkElement fe, FrameworkContentElement fce, Style oldStyle, Style newStyle, Style& styleCache)
at System.Windows.FrameworkElement.OnStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp)
at System.Windows.FrameworkElement.UpdateStyleProperty()
at System.Windows.TreeWalkHelper.InvalidateOnTreeChange(FrameworkElement fe, FrameworkContentElement fce, DependencyObject parent, Boolean isAddOperation)
at System.Windows.FrameworkElement.ChangeLogicalParent(DependencyObject newParent)
at System.Windows.FrameworkElement.AddLogicalChild(Object child)
at System.Windows.Controls.UIElementCollection.AddInternal(UIElement element)
at System.Windows.Controls.UIElementCollection.Add(UIElement element)
at System.Windows.Controls.UIElementCollection.System.Collections.IList.Add(Object value)
at Microsoft.Expression.DesignModel.InstanceBuilders.ClrObjectInstanceBuilder.InstantiateChildren(IInstanceBuilderContext context, ViewNode viewNode, DocumentCompositeNode compositeNode, Boolean isNewInstance)
Probably it loads it into an implicit WPF project. So is this some issue with Silverlight 5 XAML loading only? And if so isn’t this a potential exploit against Silverlight apps/plugin (if they allow XAML to be passed to them that is)?
It would be interesting to fix the test solution manually to not try to load the XAML file at startup, then build it and run it to see if it crashes the Silverlight plugin, the web browser, or whatever other side-effects it causes that might be exploitable.
This issue has been submitted to Microsoft at https://connect.microsoft.com/VisualStudio/feedback/details/753211/xaml-editor-window-fails-with-catastrophic-failure-when-a-style-tries-to-set-style-property. I have attached a test Silverlight project there (should be available for download soon [takes a while] from issue details)
How to space StackPanel items in XAML (has no Padding property)
While adding some properties to the back panels of ClipFlair windows, I came upon the issue of how to space items in a StackPanel. A Padding property is missing from multiple item containers (only single content controls have such), but a nice solution is described at: http://stackoverflow.com/questions/932510/how-do-i-space-out-the-child-elements-of-a-stackpanel
Sergey Aldoukhov suggested there (WPF example):
Use Margin or Padding, applied to the scope within the container:
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="0,10,0,0"/>
</Style>
</StackPanel.Resources>
<TextBox Text="Apple"/>
<TextBox Text="Banana"/>
<TextBox Text="Cherry"/>
</StackPanel>
EDIT: In case you would want to re-use the margin between two containers, you can convert the margin value to a resource in an outer scope, f.e.
<Window.Resources>
<Thickness x:Key="tbMargin">0,10,0,0</Thickness>
</Window.Resources>
and then refer to this value in the inner scope
<StackPanel.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Margin" Value="{StaticResource tbMargin}"/>
</Style>
</StackPanel.Resources>
Following up on Sergey’s suggestion there, you can define and reuse a whole Style (with various property setters, including Margin) instead of just a Thickness object:
<Style x:Key="MyStyle" TargetType="SomeItemType">
<Setter Property="Margin" Value="0,5,0,5" />
...
</Style>
…
<StackPanel>
<StackPanel.Resources>
<Style TargetType="SomeItemType" BasedOn="{StaticResource MyStyle}" />
</StackPanel.Resources>
...
</StackPanel>
Note that the trick here is the use of Style Inheritance for the implicit style, inheriting from the style in some outer (probably merged from external XAML file) resource dictionary.
Sidenote:
At first, I naively tried to use the implicit style to set the Style property of the control to that outer Style resource (say defined with the key "MyStyle"):
<StackPanel>
<StackPanel.Resources>
<Style TargetType="SomeItemType">
<Setter Property="Style" Value={StaticResource MyStyle}" />
</Style>
</StackPanel.Resources>
</StackPanel>
which caused Visual Studio 2010 to shut down immediately with CATASTROPHIC FAILURE error (HRESULT: 0x8000FFFF (E_UNEXPECTED)), as described at https://connect.microsoft.com/VisualStudio/feedback/details/753211/xaml-editor-window-fails-with-catastrophic-failure-when-a-style-tries-to-set-style-property#
Note btw that there’s an even nicer solution that Elaz Katz mentioned at that StackOverflow discussion:
It shows how to create an attached behavior, so that syntax like this would work:
<StackPanel local:MarginSetter.Margin="5">
<TextBox Text="hello" />
<Button Content="hello" />
<Button Content="hello" />
</StackPanel>
Finally, another idea could be to use WPF’s UniformGrid, although that will try to space its children evenly in the available space:
http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.uniformgrid.aspx
http://www.longhorncorner.com/uploadfile/raj1979/uniformgrid-in-wpf/
Note that it has been ported to Silverlight too:
Fix: The tag XXX does not exist in XML namespace ‘clr-namespace:YYY’
I just had some big trouble troubleshooting the Visual Studio / XAML compiler error message:
The tag XXX does not exist in XML namespace ‘clr-namespace:YYY’
It turned out this occurred because I had a Silverlight library with Assembly name X and default namespace X (at properties pane), but was using it from a demo project with Assembly name X (again!) and default namespace X.
If I removed the ";assembly=X" part from the XAML it worked fine, that is:
xmlns:my="clr-namespace:X"
Fixing the demo project to use Assembly name X.Demo and default namespace X.Demo (at its Properties pane), instead of having the same assembly name, now allows me to also use
xmlns:my="clr-namespace:X;assembly=X"
without problem.
Seems that when you have multiple assemblies with the same name in a project (wonder how the filesystem supports that), all of them are loaded fine and if they have classes with namespace X in them, the namespace gets classes from both assemblies (that’s why the xmlns without assembly=… works). When you specify assembly name in the XAML of a given project, it assumes you mean its own assembly, not any other referenced one with the same name.
BTW, at add references dialog I was using Projects option (to reference the output of other project in solution) and the project I was referencing was named X.Silverlight (can be named anything), I had not added reference the X assembly .dll file directly. Maybe that played its part too in the issue.
There may be other cases too that can cause this error to fire up, see:
http://social.msdn.microsoft.com/Forums/en/wpf/thread/56f933c8-a093-4c47-8e1a-cde4bb1864e9
HowTo: Load a XAML ResourceDictionary from a .NET assembly
Copying here my answer at:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/11a42336-8d87-4656-91a3-275413d3cc19
What seems to work for me is the following (copying from the source code of http://ClipFlair.codeplex.com [check out the FlipPanel project under “Client” subfolder])
note
I’m using Build Action = "Page" and Custom Tool="MSBuild:Compile" at the properties of Themes\DropDownTheme.xml and Themes\RotateHorizontalTheme.xaml, as was for Themes\Generic.xaml. Seems to work OK (probably this is faster at runtime compared to setting Build Action to Resource and telling it to not build it)
according to http://stackoverflow.com/questions/145752/what-are-the-various-build-action-settings-in-vs-net-project-properties-and-wh the Build Action = "Page" compiles the XAML into BAML (this seems to also apply to Silverlight 5)
* FlipPanel project, Themes\Generic.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:FlipPanel;assembly=FlipPanel"> <ResourceDictionary.MergedDictionaries> <ResourceDictionary
Source="/FlipPanel;component/Themes/RotateHorizontalTheme.xaml" /> </ResourceDictionary.MergedDictionaries> <Style TargetType="local:FlipPanel"> <Setter Property="Template"
Value="{StaticResource FlipPanel_RotateHorizontalTemplate}"/> </Style> </ResourceDictionary>
* FlipPanel Project, Themes\RotateHorizontalTheme.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:FlipPanel;assembly=FlipPanel"> <ControlTemplate x:Key="FlipPanel_RotateHorizontalTemplate"
TargetType="local:FlipPanel"> <Grid> ... </Grid> </ControlTemplate> <Style x:Key="FlipPanel_RotateHorizontalStyle" TargetType="local:FlipPanel"> <Setter Property="Template"
Value="{StaticResource FlipPanel_RotateHorizontalTemplate}"/> </Style> </ResourceDictionary>
* FlipPanel Project, Themes\DropDownTheme.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:FlipPanel;assembly=FlipPanel"> <ControlTemplate x:Key="FlipPanel_DropDownTemplate"
TargetType="local:FlipPanel"> <Grid> ... </Grid> </ControlTemplate> <Style x:Key="FlipPanel_DropDownStyle" TargetType="local:FlipPanel"> <Setter Property="Template"
Value="{StaticResource FlipPanel_DropDownTemplate}"/> </Style> </ResourceDictionary>
* FlipPanel.Silverlight.Demo project, FlipPanelTest.xaml
<UserControl x:Class="FlipPanelTest.FlipPanelTest" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:flip="clr-namespace:FlipPanel;assembly=FlipPanel" > <UserControl.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary
Source="/FlipPanel;component/Themes/RotateHorizontalTheme.xaml" /> <ResourceDictionary
Source="/FlipPanel;component/Themes/DropDownTheme.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White" Width="400"> <Grid.RowDefinitions> <RowDefinition Height="300"></RowDefinition> <RowDefinition Height="300"></RowDefinition> </Grid.RowDefinitions> <flip:FlipPanel x:Name="panel1" Grid.Row="0" BorderBrush="DarkOrange"
BorderThickness="3" CornerRadius="4" Margin="10" Background="White"
Template="{StaticResource FlipPanel_DropDownTemplate}" >
<!-- Style="{StaticResource FlipPanel_DropDownStyle}" --> <flip:FlipPanel.FrontContent> <StackPanel Margin="6"> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkOrange"
>This is the front side of the FlipPanel.</TextBlock> <Button Margin="3" Padding="3" Content="Button One"></Button> <Button Margin="3" Padding="3" Content="Button Two"></Button> <Button Margin="3" Padding="3" Content="Button Three"></Button> <Button Margin="3" Padding="3" Content="Button Four"></Button> </StackPanel> </flip:FlipPanel.FrontContent> <flip:FlipPanel.BackContent> <Grid Margin="6"> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkMagenta"
>This is the back side of the FlipPanel.</TextBlock> <Button Grid.Row="2" Margin="3" Padding="10"
Content="Flip Back to Front" HorizontalAlignment="Center"
VerticalAlignment="Center" Click="cmdFlip1_Click"></Button> </Grid> </flip:FlipPanel.BackContent> </flip:FlipPanel> <flip:FlipPanel x:Name="panel2" Grid.Row="1" BorderBrush="DarkOrange"
BorderThickness="3" CornerRadius="4" Margin="10" Background="White"
Template="{StaticResource FlipPanel_RotateHorizontalTemplate}" >
<!-- Style="{StaticResource FlipPanel_RotateHorizontalStyle}" --> <flip:FlipPanel.FrontContent> <StackPanel Margin="6"> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkOrange"
>This is the front side of the FlipPanel.</TextBlock> <Button Margin="3" Padding="3" Content="Button One"></Button> <Button Margin="3" Padding="3" Content="Button Two"></Button> <Button Margin="3" Padding="3" Content="Button Three"></Button> <Button Margin="3" Padding="3" Content="Button Four"></Button> </StackPanel> </flip:FlipPanel.FrontContent> <flip:FlipPanel.BackContent> <Grid Margin="6"> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkMagenta"
>This is the back side of the FlipPanel.</TextBlock> <Button Grid.Row="2" Margin="3" Padding="10"
Content="Flip Back to Front" HorizontalAlignment="Center"
VerticalAlignment="Center" Click="cmdFlip2_Click"></Button> </Grid> </flip:FlipPanel.BackContent> </flip:FlipPanel>
<flip:FlipPanel x:Name="panel3" Grid.Row="2" BorderBrush="DarkOrange"
BorderThickness="3" CornerRadius="4" Margin="10" Background="White" >
<!-- using default style here -->
<flip:FlipPanel.FrontContent> <StackPanel Margin="6"> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkOrange"
>This is the front side of the FlipPanel.</TextBlock> <Button Margin="3" Padding="3" Content="Button One"></Button> <Button Margin="3" Padding="3" Content="Button Two"></Button> <Button Margin="3" Padding="3" Content="Button Three"></Button> <Button Margin="3" Padding="3" Content="Button Four"></Button> </StackPanel> </flip:FlipPanel.FrontContent> <flip:FlipPanel.BackContent> <Grid Margin="6"> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <TextBlock TextWrapping="Wrap" Margin="3" FontSize="16"
Foreground="DarkMagenta"
>This is the back side of the FlipPanel.</TextBlock> <Button Grid.Row="2" Margin="3" Padding="10"
Content="Flip Back to Front" HorizontalAlignment="Center"
VerticalAlignment="Center" Click="cmdFlip2_Click"></Button> </Grid> </flip:FlipPanel.BackContent> </flip:FlipPanel>
</Grid> </UserControl>
Note that I decided to prefix names with "FlipPanel_", not sure if there’s some better way (using XAML namespaces somehow) to avoid any conflicts when merging the dictionaries and resolving the resouces with "{StaticResource …}"
Also note that in each theme file I also provide a Style (that sets the corresponding Template property of the FlipPanel conrol) that one can use instead of using the Template directly. At that Style more FlipPanel control properties could be set to values appropriate for that template (the template defines a skeleton and the style dresses the pirate [skeleton] as somebody cleverly pointed out).
Note that Generic.xaml merges and uses the templat from one of the themes. Couldmake copies of files similar to Generic.xaml and reference the same template but with different values in the Style for other properties to make variations without resorting to Copy/Paste when multiple Themes use the same Template but restyle it a bit.
Another important note is that at Generic.xaml you must not use x:Key="FlipPanel_DefaultStyle" or anyother key at the default style, or the command
public FlipPanel() { DefaultStyleKey = typeof(FlipPanel); }
won’t load the default style (which is needed when you don’t provide a Template or Style value at the consumer XAML (FlipPanelTest.xaml). Probably one can modify it to load a style by name instead of just by type (probably the issue was that it found multiple named styles applying to that type [both FlipPanel_RotateHorizontalStyle and FlipPanel_DefaultStyle] in the Generic.xaml), but removing the Key and using an unnamed style seems to do the trick.
Fix: Visual Studio 2010 XAML Designer output for WP7 light theme
The other day I submitted my 1st Windows Phone 7 application via http://create.msdn.com
Having registered for free as a student developer (being a PhD student on Robotics) via http://dreamspark.com I could only try my 1st app on WP7 emulator – when it gets accepted I will be able to have my WP7 phone unlocked to try apps there too.
So I was disappointed a bit to get back a certification failure. One of the two reasons stated was that I wasn’t following one key WP7 (design) guideline/requirement: to have the app UI work fine in both dark and light theme of WP7. I was using the default design colors and brushes, not having set any colors explicitly and since the emulator was starting in dark theme by default, this issue slipped my attention (wouldn’t it be nice if the Visual Studio XAML designer allowed you to switch between dark and light theme?).
The (nicely organized) feedback PDF from the Certification step of the WP7 app marketplace submission process was saying:
At first I couldn’t find the settings at the WP7 emulator since the image button pointing to the right to go to the settings page wasn’t visible (probably because of my video card not supporting the latest shader model and running the emulator ignoring the warnings shown that only Silverlight – not XNA – content will show up and probably not always fine – obviously meaning functionality that is implemented using GPU hardware acceleration in the emulator).
Dragging to the left on the 1st screen of the emulator (that just shows IE) takes you to the apps page where you also see Settings and your deployed app (apart from IE). You can hold down mouse on Settings there and select to Pin it to 1st page for easier access. At settings you can change the Theme Background to “light” instead of the default “dark” and try your app again.
In my app’s case indeed you couldn’t see a thing. The article that gave me a hint to what might be happening was:
http://timdams.wordpress.com/2011/06/21/creating-a-wp7-app-supporting-dark-and-light-themes/
and especially the phrase:
when the light theme is active, what WP7 basically does is switch the Foreground and the Background property of all controls, as long as they’re not defined explicitly.
The moment however, you define a specific color for a control, WP7 won’t help you with switching colors anymore
So I took a look again at the XAML code the Visual Studio 2010 designer for WP7 Silverlight app had generating. I noticed the XAML had Background=”Black” at various controls (like Grid, Pivot etc.).
Comparing with a newly created project I noticed it just had Background=”Transparent” for Grid. I later on remembered that at some point it was showing Pivot pages one over the other (due to wrong nesting in the XAML) which had set me changing the Background to “Black” at various controls trying to work around the overlap issue.
Doing a replace all for { Background=”Black”} (with a space prefix) and replacing with {} (that is nothing) is the first step needed for the fix.
The 2nd step is to add to the XAML header the missing Background="{StaticResource PhoneBackgroundBrush}" attribute value assignment shown below in bold that seems to be missing (to use the phone’s background brush by default).
In fact most probably the 2nd issue is with the Silverlight WP7 Pivot application template (probably the same goes for the Panorama template) and not the XAML designer itself which may be WP7 agnostic altogether.
<phone:PhoneApplicationPage
x:Class="MYPHONEAPPCLASSNAME.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
Background="{StaticResource PhoneBackgroundBrush}"
SupportedOrientations="PortraitOrLandscape"
Orientation="Portrait"
shell:SystemTray.IsVisible="True"
Title="MYPHONEAPPTITLE"
IsHitTestVisible="True">
A useful link regarding WP7 brushes is “Theme Resources for Windows Phone”:
http://msdn.microsoft.com/en-us/library/ff769552(v=vs.92).aspx
These suggestions have been submitted to Microsoft Connect and can be voted for at: https://connect.microsoft.com/VisualStudio/feedback/details/703467/vs2010-silverlight-xaml-designer-with-wp7-silverlight-app-templates-fail-at-wp7-light-theme