views:

26

answers:

3

I have an interesting problem. I've created a WPF UserControl which contains a button using a template:

<Button x:Name="btnStart" Template="{StaticResource RoundedGlassButton}" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="4" Height="32" Background="DarkGreen" Foreground="White" Width="72" Content="Start" />

When I place the UserControl on a parent control or form, the designer throws the error, "Could not create an instance of type 'MyUserControl'." However, while the designer won't work, the application will still compile and I get the desired results at runtime. I've narrowed the problem down to the template applied to my button. When I remove the template, the designer works:

<Button x:Name="btnStart" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="4" Height="32" Background="DarkGreen" Foreground="White" Width="72" Content="Start" />

I use this particular template all over the place - so I know it works. It even works on other UserControls. I just can't understand why it doesn't work in this particular UserControl.

Anyone have any ideas? It's hard to build a UI without being able to see the results in the visual designer.

Below is the markup for the template. Like I said, however, I'm using this all over the place with no problems. In fact, I'm even using it in other UserControls just fine. I'm just stumped as to why it won't work for this particular code.

    <ControlTemplate x:Key="RoundedGlassButton" TargetType="{x:Type Button}">
    <ControlTemplate.Resources>
        <Storyboard x:Key="Timeline1">
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="glow" Storyboard.TargetProperty="(UIElement.Opacity)">
                <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
        <Storyboard x:Key="Timeline2">
            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="glow" Storyboard.TargetProperty="(UIElement.Opacity)">
                <SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </ControlTemplate.Resources>
    <Border BorderBrush="#FF888888" BorderThickness="1,1,1,1" CornerRadius="4">
        <Border x:Name="border" Background="{TemplateBinding Background}" BorderBrush="#FF000000" BorderThickness="1,1,1,1" CornerRadius="4">                
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="0.507*"/>
                    <RowDefinition Height="0.493*"/>
                </Grid.RowDefinitions>
                <Border Opacity="0" BorderThickness="2" BorderBrush="White" HorizontalAlignment="Stretch" x:Name="glow" Width="Auto" Grid.RowSpan="2" CornerRadius="4">
                    <Border.BitmapEffect>
                        <BlurBitmapEffect Radius="2" />
                    </Border.BitmapEffect>                       
                </Border>
                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Width="Auto" Grid.RowSpan="2" SnapsToDevicePixels="True" />
                <Border HorizontalAlignment="Stretch" Margin="0,0,0,0" x:Name="shine" Width="Auto" CornerRadius="4,4,8,8">
                    <Border.Background>
                        <LinearGradientBrush EndPoint="0.494,0.889" StartPoint="0.494,0.028">
                            <GradientStop Color="#AAFFFFFF" Offset="0"/>
                            <GradientStop Color="#33FFFFFF" Offset="1"/>
                        </LinearGradientBrush>
                    </Border.Background>
                </Border>
            </Grid>
        </Border>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsPressed" Value="True">
            <Setter Property="Opacity" TargetName="shine" Value="0.4"/>
            <Setter Property="Background" TargetName="border" Value="#CC000000"/>
            <Setter Property="Visibility" TargetName="glow" Value="Hidden"/>
        </Trigger>
        <Trigger Property="IsMouseOver" Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard Storyboard="{StaticResource Timeline1}"/>
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <BeginStoryboard x:Name="Timeline2_BeginStoryboard" Storyboard="{StaticResource Timeline2}"/>
            </Trigger.ExitActions>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

Due to project deadlines, I moved the markup directly into the parent control to get around the problem for now. That said, if anyone has any ideas on what could be causing the problem - any help would still be appreciated.

A: 

Shouldn't that be Style rather than Template?

ChrisBD
Not in this case. The resource is defined as a ControlTemplate with a TargetType of Button.
bporter
Okay. I would suggest that you go to the debug options for Visual Studio and enable all of the WPF logging for the output windo.
ChrisBD
A: 

Is there some other nested exception?

I've seen this when something (like a converter inside the template) was throwing some other exception, or was relying on Application.Current for something. (app.current is VS or Blend in design time, your app at runtime)

John Gardner
A: 

Ok, I'm fairly embarrassed. As it turns out, I forgot to add a reference to the resource containing the template at the top of my UserControl markup. The first few lines of markup in my UserControl file should have looked something like the following:

    <UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/MyTemplates/MyTemplate.xaml" />
        </ResourceDictionary.MergedDictionaries>...

It's curious, though, that only the designer complained while the application still compiled and worked properly.

bporter