Question

I am currently writing a Dialog class (lookless control) which extends Window, and am assigning a default ControlTemplate to that class using a XAML style.

I want the 'Buttons' section of my Dialog template to be replacable, yet pre-populate it with a set of default buttons if nothing else is specified. This is why I added a dependency property called ButtonContent to my class.

The DefaultButtons (see XAML below) are rendered correctly when I run the application, but Visual Studio 2010's design preview does not render the content. Why is this not happening?

My dialog class looks like this:

public class Dialog : Window
{
    public FrameworkElement ButtonContent
    {
        get { return (FrameworkElement)GetValue(ButtonContentProperty); }
        set { SetValue(ButtonContentProperty, value); }
    }

    public static readonly DependencyProperty ButtonContentProperty =
        DependencyProperty.Register("ButtonContent", typeof(FrameworkElement), typeof(Dialog), new UIPropertyMetadata(null));

    static Dialog()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(Dialog), new FrameworkPropertyMetadata(typeof(Dialog)));
    }
}

This is my XAML:

<Style TargetType="{x:Type Dialogs:Dialog}">
    <Setter Property="DataContext" Value="{Binding RelativeSource={RelativeSource Self}}"/>     
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Dialogs:Dialog}">
                <StackPanel>
                    <ContentPresenter Content="{TemplateBinding ButtonContent}"/>
                    <TextBlock>This text is rendered correctly</TextBlock>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>

    <Setter Property="ButtonContent">
        <Setter.Value>
            <!-- This stuff here is not shown in VS2010's preview -->
            <UniformGrid Name="DefaultButtons" Rows="1" Columns="2">
                <Button>Button 1</Button>
                <Button>Button 2</Button>
            </UniformGrid>
        </Setter.Value>
    </Setter>
</Style>

When I launch the app, it looks like this:

As rendered by the app

The VS2010 designer renders this:

As rendered by VS2010


Edit: As described in the comments, placing the above style in Themes\Generic.xaml instead of my resource dictionary included from App.xaml does not change anything.


Edit 2: If I explicitly override the default ButtonContent like this, the designer also does not show anything. At runtime, everything works perfectly:

<Dialogs:Dialog x:Class="Dialogs.TestDialog"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Dialogs="clr-namespace:Dialogs">
    <Dialogs:Dialog.ButtonContent>
        <Button>Also not shown at design time</Button>
    </Dialogs:Dialog.ButtonContent>
</Dialogs:Dialog> 

Edit 3: If I add the ButtonContent property to a UserControl instead of my Dialog class that extends Window, the ButtonContent is displayed correctly within the user control... also, VS2010 seems to apply the style defined above to any window, not just those of class Dialog, although I have set the TargetType appropriately... weird!

Was it helpful?

Solution

I opened up a bug report at Microsoft Connect for this issue. According to MS, it is a known issue and is by design:

Thanks for reporting this issue. This is a known issue on our end and is by design. We cannot create a design instance of Window within the designer so we substitute with a proxy type of our own. That is the reason why it works correctly in a UserControl and not in a window. The workaround is to design the content of the dialog separately as a UserControl.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top