Gavin
Gavin

Reputation: 5871

Xaml - How to inject a Canvas StaticResource into a DataTemplate

On Windows Phone 8 I have a few canvas item StaticResources that I'd like to inject into a DataTemplate but can't quite figure out how to do it.

Can anyone point me in the right direction? Here's a distilled version of my XAML so far:

<phone:PhoneApplicationPage.Resources>

    <Canvas x:Key="Item1">
        ...
    </Canvas>

    <Canvas x:Key="Item2">
        ...
    </Canvas>

    <DataTemplate x:Key="SomeTemplate">
        <StackPanel Grid.Row="0" Orientation="Horizontal">
            <Viewbox Height="96" Width="96" Margin="0,12,12,0">
                <ContentControl Content="{StaticResource Item1}" />
            </Viewbox>
        </StackPanel>
    </DataTemplate>

</phone:PhoneApplicationPage.Resources>

When run I get an unhandled exception of: "Error HRESULT E_FAIL has been returned from a call to a COM component."

Upvotes: 0

Views: 2343

Answers (3)

Amit Bhatiya
Amit Bhatiya

Reputation: 2621

Try this:

    <Grid>
        <Canvas Margin="10" Background="AliceBlue">
            <ItemsControl ItemsSource="{Binding}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Canvas>
                            <TextBlock Canvas.Left="{Binding Left}" Canvas.Top="{Binding Top}" Text="{Binding Text}" Width="50" Height="20" Foreground="Black"/>
                        </Canvas>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Canvas>
    </Grid>

Upvotes: 0

yasen
yasen

Reputation: 3580

You cannot have controls as resources. One UI element cannot be in two places of the visual tree at the same time, so that makes it pointless to have controls as resources.

Here's an idea, but I'm not sure how it will perform if you use a lot of these resources. I tested it quickly and it seems to work, but I haven't used it for real, so there might be some issues in some cases.

  1. Wrap the Canvas from the resources in a DataTemplate like this:

    <DataTemplate x:Key="Item1">
        <Canvas>
            ...
        </Canvas>
    </DataTemplate>
    
  2. Use this template for ContentControl's ContentTemplate property like this:

    <DataTemplate x:Key="SomeTemplate">
        ...
           <ContentControl ContentTemplate="{StaticResource Item1}" />
        ...
    </DataTemplate>
    

Hope this helps! :)

Upvotes: 3

Sheridan
Sheridan

Reputation: 69959

You seem to be somewhat confused as to how WPF works. You cannot inject Canvas controls from resources into XAML. The best that you can do is to create a Style for your Canvas and then apply that Style to a new Canvas in your XAML. However, it should be noted that you cannot set the Canvas.Children property from that Style... this would cause an error:

<Style TargetType="{x:Type Canvas}">
    <Setter Property="Children">
        <Setter.Value>
            <Button Content="Click me!!" />
        </Setter.Value>
    </Setter>
</Style>

However, it is possible to 'pre-define' controls in a Style, but you would have to use a ContentControl to display it. Try this:

<Style TargetType="{x:Type ContentControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ContentControl}">
                <Canvas>
                    <Button Content="Click me!!" />
                </Canvas>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Now when you can see the Button in the Canvas whenever you use this XAML:

<ContentControl />

Upvotes: 1

Related Questions