5

I have implemented a user control that lets me build several similar interface screens quickly. Basically it defines two dependency properties MainContent and UserInteractions which are then displayed in the visual template (xaml in a ResourceDictionary) looking like this:

+-------------+
| L |         |
| o |  Main   |
| g | Content |
| o |         |
+---+---------+
| Interaction |
+-------------+

Xaml for a screen then looks like this:

<controls:ScreenControl>
    <controls:ScreenControl.MainContent>
        <TextBlock>Some content goes here</TextBlock>
    </controls:ScreenControl.MainContent>
    <controls:ScreenControl.UserInteractions>
        <Button>Do something</Button>
    </controls:ScreenControl.UserInteractions>
</controls:InstallerScreenControl>

This works fine when I run the application. However, in the designer, nothing is visible. Not the content defined explicitly in the view, and not the stuff from the template. What do I need to add to enable design support? I tried moving the template to Themes/Generic.xaml as was suggested in some places, but that made no difference. This SO question seems related, but gets no useful answer.

EDIT: My ScreenControl looks like this:

public class ScreenControl : UserControl
{
    public object MainContent
    {
        get { return GetValue(MainContentProperty); }
        set { SetValue(MainContentProperty, value); }
    }
    public static readonly DependencyProperty MainContentProperty = DependencyProperty.Register(
        name: "MainContent",
        propertyType: typeof(object), 
        ownerType: typeof(ScreenControl),
        typeMetadata: new PropertyMetadata(default(object)));


    public object UserInteractions
    {
        get { return GetValue(UserInteractionsProperty); }
        set { SetValue(UserInteractionsProperty, value); }
    }
    public static readonly DependencyProperty UserInteractionsProperty = DependencyProperty.Register(
        name: "UserInteractions",
        propertyType: typeof(object),
        ownerType: typeof(ScreenControl),
        typeMetadata: new PropertyMetadata(default(object)));
}

When a screen using the control is viewed in the designer, it only shows this:

Nothing here...

Ie, nothing, only a blank box.

When using the control, I'm creating a UserControl, adding the Xaml shown in the beginning of the question, and removing the code-behind file.

Community
  • 1
  • 1
carlpett
  • 12,203
  • 5
  • 48
  • 82

1 Answers1

2

You must inherit your custom control from Control and not UserControl for having the template applied.

It's hard to tell with the information you are giving, but you must have a static constructor that applies the template.

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

May not be your issue when reading further, not sure you have some InDesignMode somewhere? Calls in your code that only works when the application is running? IE WebService calls? Just guessing here, but alot of things may cause the designer to break.

Stígandr
  • 2,874
  • 21
  • 36
  • The template is applied, so it works in runtime, but in designer mode, it's just a blank page (not even a designer exception). I'll try to clarify in the question. There are no external calls or anything else in place yet, really. Just visuals. – carlpett Jul 23 '14 at 12:01
  • I tried inheriting from `Control` instead of `UserControl`, but couldn't see any difference, neither in design-time or runtime. – carlpett Jul 23 '14 at 12:09
  • Override the OnApplyTemplate Method and set a break point there, see if it gets called in your designer. – Stígandr Jul 23 '14 at 14:03
  • Interestingly, no. It is not called at design-time. It _is_ called at runtime though. – carlpett Jul 23 '14 at 14:23
  • 2
    (For a future reader who, like me, does not know how to debug the designer, check http://stackoverflow.com/a/12843372/124178) – carlpett Jul 23 '14 at 14:23
  • From this answer I got the final piece of the puzzle: http://stackoverflow.com/a/13997701/124178. Adding the Themes/Generic.xaml file, the `ThemeInfo` attribute and the static constructor, I finally got the designer support. Thanks! Could you edit that into the answer? – carlpett Jul 23 '14 at 14:53
  • @carlpett Excelent, but if I would still have used control as a baseclass rather than UserControl, since it's templated. This is what we call customcontrols in the WPF & SL eco system. – Stígandr Jul 24 '14 at 12:22
  • Ah, yes. I switched that as well, sorry about forgetting to mention it. It does not seem to affect this, however, the designer is happy either way. – carlpett Jul 24 '14 at 14:37
  • 1
    Is this accepted answer the actual solution? Is it WPF related? I'm having the exact same issue in WinRT-XAML and the solution proposed doesn't compile at all. – MBender Jun 20 '16 at 10:41
  • Doesn't Control class inherit from UserControl? [See MSDN](https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.usercontrol?view=netframework-4.7.2). If Control is templated, UserControl should be as well. – blearyeye Sep 19 '18 at 21:52