Title: Visual Studio Designer shows empty Window when using custom ContentPropertyAttribute
Tags: c#;wpf;visual-studio;designer
Question: My application has a lot of windows and most of them share some basic features. Because of that I extended the Window class to create a base for all my windows.
Everything compiles and displays fine but the designer just shows an empty window when I use my window class.
I made a basic example that can be easily used, my real window is much more complex but this shows the problem.
Here is the code:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Markup;
namespace WpfApplication1
[ContentProperty("ContentElement")]
public class MyWindow : Window
public ToolBar ToolBar { get; private set; }
public StatusBar StatusBar { get; private set; }
public Border ContentBorder { get; private set; }
public UIElement ContentElement
{
get { return (UIElement)GetValue(ContentElementProperty); }
set { SetValue(ContentElementProperty, value); }
}
public static readonly DependencyProperty ContentElementProperty = DependencyProperty.Register(
"ContentElement", typeof(UIElement), typeof(MyWindow),
new PropertyMetadata(null, (d, e) =&gt;
{
MyWindow w = (MyWindow)d;
w.ContentBorder.Child = (UIElement)e.NewValue;
}));
public MyWindow() : base()
{
ToolBar = new ToolBar();
ToolBar.Height = 30;
ToolBar.VerticalAlignment = VerticalAlignment.Top;
StatusBar = new StatusBar();
StatusBar.Height = 20;
StatusBar.VerticalAlignment = VerticalAlignment.Bottom;
ContentBorder = new Border();
ContentBorder.SetValue(MarginProperty, new Thickness(0, 30, 0, 20));
Grid grid = new Grid();
grid.Children.Add(ToolBar);
grid.Children.Add(ContentBorder);
grid.Children.Add(StatusBar);
Content = grid;
}
XAML example for using MyWindow:
<local:MyWindow x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="300"&gt;
<Grid&gt;
<Rectangle Fill="Blue" /&gt;
</Grid&gt;
</local:MyWindow&gt;
Doing the exact same thing with a UserControl works just fine, also in the designer. Just replace every occurance of MyWindow with MyUserControl and extend from UserControl if you want to try that.
Is there any way I can get a custom Window like that to work with the designer, or do i have to make a UserControl and use that in every window?
Also, is this some kind of bug or intended behavior?
Addional info: I'm running Visual Studio 2015 Community and I'm using .net 4.6
I Also tried another approach. Instead of using the ContentPropertyAttribute i have overwritten the ContentProperty like this:
new public object Content {
get { return GetValue(ContentProperty); }
set { SetValue(ContentProperty, value); }
new public static DependencyProperty ContentProperty = DependencyProperty.Register("Content", typeof(object), typeof(BaseUserControl), new PropertyMetadata(null, (s, e) =&gt;
MyWindow bw = (MyWindow)s;
bw.ContentBorder.Child = (UIElement)e.NewValue;
Again this works completely fine with a UserControl. With a Window I can at least see the Content in the designer now, but the ToolBar and StatusBar are still not showing up in the designer. When running it everything works correctly.

Here is the accepted answer: First, I am no super expert on WPF, but have done a bunch and think I can offer and help clarify some components.  First, you can NOT derive from a .XAML based declaration of a WPF-Window, it can only be if entirely within code.  I have come to find that sometimes the visual element building is much easier to do in XAML than it is within code, but both can and do work.
So, that said, I would like to offer a solution that might work for you.  Starting with WPF Window Style / Templatea, if you are not already familiar with them, along with other controls you can run through their defaults.
First, I am starting with a RESOURCE DICTIONARY STYLE definition that will mimic much of what you may want in your default form.  This becomes the stuff within the "ControlTemplate" of the style definition.  I have created this as a file "MyWindowStyle.xaml" at the root level WpfApplication1 I created on my machine (just to match your sample project file namespace reference).
Inside the template, you could have almost anything... grids, dock panel, stack panels, etc.  In this case, I have used a DockPanel and added your sample ToolBar, StatusBar and two extra labels just for sample.  I also preset size and bogus color just to give visualization of the parts when you confirm their impact.
The CRITICAL element to look at is the .  This identifies where the content for each of your DERIVED Windows content will be placed... Think of it as a place-holder for each one of your forms for individuality while the rest of the form, its controls all remain consistent.  You will see it come into play as you play around with it.
The content of it is and notice the style x:Key="MyWindowStyle".  This coincidentally is the same as the xaml, but you could have 100's of styles within a single resource dictionary.  I am keeping simple to just the one for demo purposes.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" &gt;
<Style x:Key="MyWindowStyle" TargetType="Window"&gt;
<Setter Property="SnapsToDevicePixels" Value="true" /&gt;
<Setter Property="Template"&gt;
<Setter.Value&gt;
<ControlTemplate TargetType="{x:Type Window}"&gt;
<Grid&gt;
<Grid.Background&gt;
<SolidColorBrush Color="{DynamicResource WindowColor}"/&gt;
</Grid.Background&gt;
<AdornerDecorator&gt;
<DockPanel LastChildFill="True" Background="Blue"&gt;
<!-- List items docked to the top based on top-most first going down --&gt;
<ToolBar x:Name="tmpToolBar" Height="45" DockPanel.Dock="Top" /&gt;
<Label Content="Testing by Style"
Height="30" Width="150" DockPanel.Dock="Top"/&gt;
<!-- When docking to the bottom, start with bottom most working up --&gt;
<StatusBar x:Name="tmpStatusBar" Height="30"
Background="Yellow" DockPanel.Dock="Bottom" /&gt;
<Label Content="Footer area based from style"
Height="30" Width="250" DockPanel.Dock="Bottom" /&gt;
<!-- This one, since docked last is rest of the space of the window --&gt;
<ContentPresenter DockPanel.Dock="Bottom"/&gt;
</DockPanel&gt;
</AdornerDecorator&gt;
<ResizeGrip x:Name="WindowResizeGrip"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Visibility="Collapsed"
IsTabStop="false" /&gt;
</Grid&gt;
<ControlTemplate.Triggers&gt;
<Trigger Property="ResizeMode" Value="CanResizeWithGrip"&gt;
<Setter TargetName="WindowResizeGrip"
Property="Visibility" Value="Visible" /&gt;
</Trigger&gt;
</ControlTemplate.Triggers&gt;
</ControlTemplate&gt;
</Setter.Value&gt;
</Setter&gt;
</Style&gt;
</ResourceDictionary&gt;
Next, we need to make this publicly available for the entire duration of the application, including availability within the designer mode...  Within your projects "App.xaml" which is the startup for the application, it will have a default and empty  area.  Replace it with this.
<Application.Resources&gt;
<ResourceDictionary&gt;
<ResourceDictionary.MergedDictionaries&gt;
<ResourceDictionary  Source="pack://application:,,,/WpfApplication1;component/MyWindowStyle.xaml" /&gt;
</ResourceDictionary.MergedDictionaries&gt;
</ResourceDictionary&gt;
</Application.Resources&gt;
Now, to a CODE-ONLY (not a .xaml window based definition) of your "MyWindow.cs" class.  If you look at the style where I declared the toolbar and statusbar, I assigned them the names of "tmpToolBar" and "tmpStatusBar" respectively.  Notice the [TemplatePart()] declarations.  I am now expecting the template to HAVE these controls by the given name within the TEMPLATE somewhere.
Within the constructor, I am loading the Style from the App.xaml resource dictionary being fully available.  Then I follow-up with the OnApplyTemplate() which I typically heavily document my code so anyone following me has some idea how / where things originated from and self explanatory.
My entire "MyClass.cs" is below
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
namespace WpfApplication1
[TemplatePart(Name = "tmpToolBar", Type = typeof(ToolBar))]
[TemplatePart(Name = "tmpStatusBar", Type = typeof(StatusBar))]
public class MyWindow : Window
protected ToolBar myToolBar;
protected StatusBar myStatusBar;
public MyWindow() : base()
{
// NOW, look for the resource of "MyWindowStyle" within the dictionary
var tryStyle = FindResource("MyWindowStyle") as Style;
// if a valid find and it IS of type Style, set the style of
// the form to this pre-defined format and all it's content
if (tryStyle is Style)
Style = tryStyle;
}
// the actual template is not applied until some time after initialization.
// at that point, we can then look to grab object references to the controls
// you have need to "hook up" to.
public override void OnApplyTemplate()
{
// first allow default to happen
base.OnApplyTemplate();
// while we get the style loaded, we can now look at the expected template "parts"
// as declared at the top of this class.  Specifically looking for the TEMPLATE
// declaration by the name "tmpToolBar" and "tmpStatusBar" respectively.
// get object pointer to the template as defined in the style template
// Now, store those object references into YOUR Window object reference of Toolbar
var myToolBar = Template.FindName("tmpToolBar", this) as ToolBar;
if (myToolBar != null)
// if you wanted to add your own hooks to the toolbar control
// that is declared in the template
myToolBar.PreviewMouseDoubleClick += myToolBar_PreviewMouseDoubleClick;
// get object pointer to the template as defined in the style template
var myStatusBar = Template.FindName("tmpStatusBar", this) as StatusBar;
if (myStatusBar != null)
myStatusBar.MouseDoubleClick += myStatusBar_MouseDoubleClick;
// Now, you can do whatever else you need with these controls downstream to the
// rest of your derived window controls
}
void myToolBar_PreviewMouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
// in case you wanted to do something based on PreviewMouseDoubleClick of the toolbar
MessageBox.Show("ToolBar: Current Window Class: " + this.ToString());
}
void myStatusBar_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
// in case something for MouseDoubleClick on the StatusBar
MessageBox.Show("StatusBar: Current Window Class: " + this.ToString());
}
So now, lets put it into place.  Have your application's main window derive from the MyWindow class.  The only thing you need there is
namespace WpfApplication1
public partial class MainWindow : MyWindow
{}
In the DESIGNER of your form, put in a few controls, such as label, textbox, whatever.  You do not see your actual other style yet, but just go with it.  Save and run the sample app.  Your main window should be displayed with the entire pre-defined template there ALONG WITH the few extra control you had placed specifically on this form.
Now, to get the full visualization in your "MainWindow" from the designer perspective.  Within the .xaml area of
<my:MyWindow
x:Class="WpfApplication1.MainWindow"
[other declarations]  &gt;
just add the following before the close ">"
Style="{StaticResource MyWindowStyle}"
The resource is available via the App.xaml at startup and you should now be able to see the entire visual while you are designing... but you cant change the outermost template, just the content specific to this one page as mentioned about the "ContentPresenter" part of the template definition.  What you are changing is within the place-holder portion allocated by the Template.  If you want to change the main part of the window controls, you need to update the TEMPLATE!
But here is part of the trick of the template designer.  Start with this, and build in what you need visually, get it placed right and once ready, take it out of here and put into the template and now it is applicable to the rest of all windows.  Fix fonts, sizes, colors, whatever.
Hope this helps, and if you have any questions for follow-up, let me know.
Comment for this answer: Thanks. I will accept this as an answer if nothing better comes. The usage of `Template` is one of the workarounds I have used. Sadly it still requires me to set the Template property or Style property for every new Window. The other workaround I know about is to derive from `UserControl` instead of `Window`, add it to the Window in xaml and then accessing the subcontrols through it. I prefer the `Template` solution though because it makes the access to the child controls more easy.
Comment for this answer: I still don't understand why `Window` behaves different then `UserControl` in the Designer. They are practically the same when i comes to the Designer. The only difference is that `Window` gets a gray border as far as i can tell. But well, maybe it will work in some future versions
Comment for this answer: I have tried your solution and it works but to make it work in the designer i have to set the template in xaml. Or did I do something wrong? Making it work in the designer is the the whole idea of this exercise :). Another small weakness of the Template workaround is that, when i put this Window in a libary I actually have to add the ResourceDictionary to every App that is using it (My nested UserControl solution does not have that problem). But for now thats not a concern for me
Comment for this answer: no need for extra effort on you part. Just tell me if I did something wrong: For me, it only shows the ToolBar and the StatusBar in the designer when I set the template property in xaml. At runtime it's fine without it obviously. Is that different for you?
Comment for this answer: @x4rf41,  The solution I have does not require you to set the style/template in every new window...  Look at MyWIndow() costructor.  It looks for the resource of the style and assigns it at run-time for you.  You don't need to do anything else.  Then, when the template is applied, gets the hooks for the toolbar and status bar too. so the parts are available for your child derived forms.
Comment for this answer: @x4rf41, from within the app, you dont NEED to explicitly add the style reference, it will auto-load.  However, whatever the window-specific page you want is all that will be different when presented.  The baseclass MyWindow forces load the style.  Let me see about turning this into a library dll for you aside IN ADDITION to this answer.
Comment for this answer: @x4rf41, I also had two bogus "labels" acting like a header and footer just to show context of other stuff you COULD have in your outer template and the center "ContentPresenter" is where each of YOUR form controls would be visually applicable.

Here is another answer: Window class is very complex in compare to UserControl class. Microsoft has written more than 8k lines of code in Window class compare to 80 lines in UserControl, additionally Window class contain many operation/event/restriction on content property, and any one piece of code is hindering in rendering the content when you use [ContentProperty("ContentElement")] with the Window subclass MyWindow .
Probably making it a UserControl is better option, If not possible you can write some code temporarily(copy code from ContentElement property) in content property to see the design view.
<lib:MyWindow.Content&gt;
<Button  Content="Click"   Width="200"   /&gt;
</lib:MyWindow.Content&gt;
and then just remove the code before run time. (Not a good idea but, whatever works.:) and I suspect that you have  already figured that out.

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 2, 'CommentCount': 0, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2015:00:09/20/15', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<c#><wpf><visual-studio><designer>', 'Title': 'Visual Studio Designer shows empty Window when using custom ContentPropertyAttribute', 'ViewCount': 1289, 'id': 32674929, 'user_AboutMe': None, 'user_AccountId': 104025.0, 'user_DisplayName': 'x4rf41', 'user_Reputation': 5036.0, 'user_Views': 440.0, 'user_id': 278329.0}}