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:
The VS2010 designer renders this:
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!
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.