R – wpf to silverlight xaml issue

silverlightwpfxaml

Ok, I have a ResourceDictionary definition that I used for a WPF app below:

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<Style x:Key="fieldsPanel" TargetType="{x:Type StackPanel}">
    <Style.Resources>
        <Style TargetType="{x:Type CheckBox}">
            <Setter Property="Margin" Value="8 2" />
        </Style>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="Margin" Value="0 2" />
            <Setter Property="Width" Value="100" />
        </Style> 
    </Style.Resources>
</Style>

This exact block of XAML, when brought into my Silverlight app, shows 4 errors in the error pane (the first error appears 3 times, the second once)

  1. The tag 'Type' does not exist in XML namespace 'http://schemas.microsoft.com/winfx/2006/xaml'

  2. The property 'Resources' does not exist on the type 'Style' in the XML namespace 'http://schemas.microsoft.com/winfx/2006/xaml/presentation'

I can make all instances of the first error go away by replacing the "{x:Type TypeName}" text with "TypeName". But is this the correct way to fix this? Is this just another random and arbitrary difference between WPF and Silverlight?

But I can't figure out what I'm doing wrong in the second error. Can anyone give me some help (and the place you found the answer)?

EDIT:

If I knew how to Google "Style.Resources" (so that Google wouldn't ignore the dot) or if I knew the terminology for what that type of construct is called, I think could figure it out for myself.

EDIT:

It turns out that what I was trying to accomplish is probably best done with a UserControl. But apparently I need to learn a whole new set of rules for making UserControls in Silverlight.

In short, I want something like this:

<CheckBox Click="myClickHandler"  Name="myName"/><TextBlock Text="The label for the checkbox" />

…made into a UserControl which I can instantiate several times with different names and labels. All checkboxes will use the same click handler.

If anyone wants to whip up some quick UserControl code and post it, I'd appreciate it. If not (and I totally understand not wanting to do free work for someone else), I'll start Googling.

Best Answer

At first sight it appears to be the correct way to fix the problem and it does appear to be "another random and arbitrary difference" between WPF and Silverlight. However, making that change doesn't actually produce code that works.

As Klay correctly points out in his latest edit, what he actually needs to do is produce a UserControl with the Dependency Properties for the variable parts (Text etc.).

Here's the ResourceDictonary page on MSDN which has more information on the format.

Don't forget the Silverlight is not really a sub-set of WPF. Microsoft had to completely rewrite the code that runs Silverlight apps so that the runtime is a small download.

EDIT

The XAML you need is:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MyControls">
    >
    <Style TargetType="StackPanel">
        <Setter Property="Template">
            <Setter.Value>
                <Control Template TargetType="local:myPanel">
                    <CheckBox x:Name="myCheckBox"
                              Content="{TemplateBinding CheckBoxLabel}"
                              Margin="8,0,2,0" Width = "100"/>
                </Control>
            </Setter.Value>
         </Setter>    
    </Style>
</ResourceDictionary>

Then you'll need to create a cs file containing the code for your user control:

namespace MyControls
{
    public class myPanel : ContentControl
    {
        public myPanel()
        {
            DefaultStyleKey = typeof(myPanel);
        }
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        CheckBox checkbox = GetTemplateChild("myCheckBox") as CheckBox;
        checkbox.Click += CheckBoxClick;
    }

    void CheckBoxClick(object sender, RoutedEventArgs e)
    {
        CheckBox checkbox = sender as CheckBox;
        // Do this CheckBox specific stuff
    }

    public string CheckBoxLabel
    {
        get { return (string)GetValue(CheckBoxLabelProperty); }
        set { SetValue(CheckBoxLabelProperty, value); }
    }

    public static readonly DependencyProperty CheckBoxLabelProperty =
        DependencyProperty.Register("CheckBoxLabel", typeof(string),
                                    typeof(myPanel), null);
 }

Disclaimer - I've just put this together from a more complex user control so there's no guarantee that it'll work "out of the box". You'll probably need to tweak it a bit to get it working 100%.

Related Topic