4

I have created a simple WPF custom control which inherits from Window, so that later I am able to override it's chrome and reuse it across my projects. The control is contained in its own project along with a generic.xaml file (in the Themes directory). The style for the control simply sets a red background. Within a second project (same solution) I then use the control as the base class of a new WPF window. When I now compile the project and have it run, it shows my (custom-)window with the desired red background.

My question is now: how do I get the WPF designer to show the generic style (in this case the red background) at design time?

When I do the same with, say, a button then the generic style is applied at design time automatically. But any default style of a control inheriting from Window will only show at runtime. What am I missing?

control code:

public class CustomControl1 : Window
{
    static CustomControl1()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
    }
}

generic.xaml:

<Style TargetType="{x:Type local:CustomControl1}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomControl1}">
                <Border Background="Red"/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

The XAML of the test window in the second project where I use the control:

<snh:CustomControl1 x:Class="WpfDockWindow.TestWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:snh="clr-namespace:SnH.WpfControls;assembly=SnH.WpfControls"
    Title="TestWindow" Height="300" Width="300">
<Grid>

</Grid>

And for the records, I use VS2013 and the projects are compiled with framework 4.5.1.

Thx, Ben

Ben
  • 41
  • 2
  • I think it is a known issue. it is somewhat relate to [WPF Style for base window not applied in App.xaml, but is in Themes/Generic.xaml](http://stackoverflow.com/questions/14383696/wpf-style-for-base-window-not-applied-in-app-xaml-but-is-in-themes-generic-xaml) – pushpraj Aug 31 '14 at 02:19
  • Did you find a solution to this problem? I'm having the same behavior... – Rico Suter Feb 25 '15 at 13:47
  • Six years later and I have this same issue. In my case, neither suggested answers. I have everything defined in one test project, so no difference of target cpu settings to deal with. I've tried various cpu targets to no avail. And I MUST use Window as my custom control base because I'm replacing the WindowChrome with my own custom look for the window with transparency and custom event handlers that need to live at the Window level. Has anyone had any luck with getting a custom Window control to show up correctly at design-time in Visual Studio? (I'm currently on VS2017, Framework 4.6.1). – nedmech Mar 18 '21 at 17:51

2 Answers2

0

How about trying a different approach? Instead of inheriting the custom control from Window, try to inherit it from ContentControl and then use it inside a regular Window as a top level control and define its content.

The custom control should look like

namespace ProjectBar.Controls
{
    public class CustomControl : ContentControl
    {
        static CustomControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl), new FrameworkPropertyMetadata(typeof(CustomControl)));
        }
    }
}

Now lets define the default control template in ProjectBar\Themes\Generic.xaml

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:ProjectBar.Controls">
  <Style TargetType="{x:Type controls:CustomControl}">
    <Setter Property="Background" Value="Red"/>
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="{x:Type controls:CustomControl}">
          <Grid Margin="5" Background="{TemplateBinding Background}">
            <Grid.RowDefinitions>
              <RowDefinition Height="*"/>
              <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <!--Define the ContentPresenter. This is the place where the Content goes-->
            <ContentPresenter Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center"/>

            <!--Place the OK and Cancel buttons-->
            <StackPanel Orientation="Horizontal" FlowDirection="RightToLeft" Grid.Row="1" >
              <Button Content="Cancel" HorizontalAlignment="Right" Width="60" />
              <Button Content="OK" HorizontalAlignment="Right" Width="60" />
            </StackPanel>
          </Grid>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</ResourceDictionary>

Usage in the ProjectFoo

<Window x:Class="ProjectFoo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:controls="clr-namespace:ProjectBar.Controls;assembly=ProjectBar"
        Title="MainWindow" Height="200" Width="300">
    <controls:CustomControl>
        <Label>Place anything here</Label>
    </controls:CustomControl>
</Window>

But I know, you don't like the red color, lets change it in the ProjectFoo in the App.xaml file

<Application x:Class="ProjectFoo.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:controls="clr-namespace:ProjectBar.Controls;assembly=ProjectBar"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <Style TargetType="{x:Type controls:CustomControl}">
            <Setter Property="Background" Value="Green"/>
        </Style>
    </Application.Resources>
</Application>

EDIT: Also make sure to add this line in the ProjectBar AssemblyInfo.cs

[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
Aldaris
  • 71
  • 8
0

i have spend a lot of time trying resolve this issue.

And the answer has: ----> Change my Platform Settings of the Reference Project (Control Project) and the Consuming Project to be the Any Cpu

If the "Control Project" was setup as "Any Cpu" and you are trying to use in the "Consuming Project" as x64, the issue occours. The Correct Configuration (Sorry about English)