Solved

Using code from base class at design time with WPF

Posted on 2014-09-18
6
248 Views
Last Modified: 2014-11-27
Here’s an interesting problem:

      I want to use a custom window as a base for other windows in my project. I’ve tried this before and learned the lesson that you can have visual inheritance with XAML. So I decided I would define the base class via code, since I don’t have that much I need to add, but I’m running into a problem.
      Here’s my scenario. First I have my base class:

Public Class TheBase
    Inherits Window

    Public Sub New()
        Dim MainGrid As New Grid

        Content = MainGrid

        MainGrid.Children.Add(New TextBlock With {.Text = "This is a test"})
    End Sub
End Class

Open in new window


      Then I have the class that inherits it:

Public Class TheFinalWindow

End Class

Open in new window


      The XAML for it is:

<MyNS:TheBase x:Class="TheFinalWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    mc:Ignorable="d"
    xmlns:MyNS="clr-namespace:MyNamespace">

</MyNS:TheBase>

Open in new window


      When I run the code to show an instance of TheFinalWindow, I see the TextBlock which says “This is a test”, but when I open up TheFinalWindow in design mode, it doesn’t appear. In my actual project, I’m trying to add a container to “TheBase” and then put controls into it through “TheFinalWindow”, but I haven’t gotten any farther than this. I definitely need design time support for this so I can make “TheFinalWindow” without having to run the code every three seconds to see what I’m doing.
      What can I do to fix this?
0
Comment
Question by:BROOKLYN1950
  • 3
  • 2
6 Comments
 
LVL 25

Expert Comment

by:apeter
ID: 40335637
You have to override some of the methods in your custom window. Hope this links helps you, http://blog.magnusmontin.net/2013/03/16/how-to-create-a-custom-window-in-wpf/
0
 

Author Comment

by:BROOKLYN1950
ID: 40348010
Okay, thanks to apeter I seem to be onto something. I followed his link and learned quite a bit. It seems like I should be able to do this through control templates, since it doesn't cause the error of inheriting from a class defined in XAML.
I've been looking into default control templates for custom classes (i.e. defining a style in Themes\Generic.xaml). So far the best example I could find is this:

http://svetoslavsavov.blogspot.com/2009/09/user-control-inheritance-in-wpf.html

In his second example ("Variant 2" as he calls it), he creates a custom control with a style in Generic.xaml and then inherits from it to make a user control which he then adds content to. I downloaded the source code and confirmed that everything works in the designer as well as at runtime.
The problem is that when I try to do the same thing with a window, it doesn't show it in the designer. I've attached a modified version of his source code in which I try to show his inherited control inside my inherited window. The style defined in Generic.xaml doesn't get applied to the design time window but it works fine at run time.

Any ideas on how to make the window work like the user control does?
0
 
LVL 25

Expert Comment

by:apeter
ID: 40375726
Hope these link gives you some idea. https://wpfwindow.codeplex.com. and this as well, http://3water.wordpress.com/2013/02/16/metro-style-window-in-wpf/

What you are trying to customise your window ?
0
 

Accepted Solution

by:
BROOKLYN1950 earned 0 total points
ID: 40460074
Okay, so I finally figured it out through trial and error and some lucky ideas. Here's what I had to do:

First off I had to define a custom Style with ControlTemplate in my "Generic.xaml" file. To do this I used Blend to get the default ControlTemplate for Window and then modified it to fit my needs (I added a Button on the bottom as well as a few other things).

I then added a block like this to my "TheBase" class:

Public Shared Sub New()
    DefaultStyleKeyProperty.OverrideMetadata(GetType(TheBase), New FrameworkPropertyMetadata(GetType(TheBase)))
End Sub

Open in new window


I also overrode the OnApplyTemplate method to get access to the custom elements I added in the ControlTemplate (i.e. the Button I mentioned above). I then added any functionality I wanted in all my "child" classes into my "TheBase" class (i.e. what I wanted the button to do when it was clicked).

So in the end my base class looked like this:

Public Class TheBase
    Inherits Window

    Private _MyButton As Button
    Friend ReadOnly Property MyButton As Button
        Get
            Return _MyButton
        End Get
    End Property

    Public Shared Sub New()
        DefaultStyleKeyProperty.OverrideMetadata(GetType(TheBase), New FrameworkPropertyMetadata(GetType(TheBase)))
    End Sub

    Public Overrides Sub OnApplyTemplate()
        MyBase.OnApplyTemplate()

        _MyButton = GetTemplateChild("PART_MyButton")
    End Sub

    'Custom window logic here

End Class

Open in new window


Next I went on to making my first "child" class. I added a new Window to my project, but changed the beginning and ending tags from "Window" to "MyNS:TheBase".

Now here's the trick that got it to work at design time. I had to add this to my "child" class:

    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/MyNS;component/Themes/Generic.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>

Open in new window


Once I added that, everything work at both design time and runtime.

Note that I did not have to override any existing Window logic (such as the Minimize and Maximize buttons) as had been suggested in some of the links above.

I hope this helps out anyone else who has this problem, even though it seems to be a very rare need.
0
 

Author Closing Comment

by:BROOKLYN1950
ID: 40468679
I was the one who ultimately got a solution to my problem. Though some of the comments did help point me in the right direction, I had to piece everything together and mess around until I actually got it working.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
adobe acrobat scaning 9 50
XSLT XML 4 14
Error on link 14 38
Signing certificate through internal CA server windows server 2008 11 35
Many times as a report developer I've been asked to display normalized data such as three rows with values Jack, Joe, and Bob as a single comma-separated string such as 'Jack, Joe, Bob', and vice versa.  Here's how to do it. 
Join Greg Farro and Ethan Banks from Packet Pushers (http://packetpushers.net/podcast/podcasts/pq-show-93-smart-network-monitoring-paessler-sponsored/) and Greg Ross from Paessler (https://www.paessler.com/prtg) for a discussion about smart network …
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now