1

Usual WPF architecture:

public partial class MainWindow: Window {

... InitializeComponent()

}

XAML: <Window x:Class="MainWindow"> </Window>

What I want to move to:

public abstract class BaseWindow: Window {

    public System.Windows.Controls.TextBlock control1;
    public System.Windows.Shapes.Rectangle   control2;
    public System.Windows.Controls.TextBox   control3;

}

public partial class AWindowImplementation {

... InitializeComponent()

}

public partial class AnotherWindowImplementation{

... InitializeComponent() 

}

 XAML:
 <BaseWindow x:Class="AWindowImplementation"> </BaseWindow>
 <BaseWindow x:Class="AnotherWindowImplementation"> </BaseWindow>

The above is pseudo-code. This new architecture compiles, with warnings that the implementations hide the control defintions (because the place where I should put the 'override' keywords are withing the auto-generated InitializeComponent). Unfortunately the control fields don't get populated.

Is this achievable? What I am trying to do is create several UI designs with the same interface/controls so that the rest of the code can interact with either design.

EDIT: Thanks to pchajer and Yevgeniy, I now have the following working solution, but I still get override warnings:

 public class MainWindowBase : Window
 {
     public TextBlock control1;
     public Rectangle control2;
     public TextBox   control3;

    static MainWindowBase()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MainWindowBase),
                   new FrameworkPropertyMetadata(typeof(MainWindowBase)));
    }

    public override void OnApplyTemplate()
    {
        control1 = (TextBlock) FindName("control1");
        control2 = (Rectangle) FindName("control2");
        control3 = (TextBox)   FindName("control3");
    }

 }   

 <Style TargetType="{x:Type views:MainWindowBase}" 
           BasedOn="{StaticResource {x:Type Window}}">
     <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type views:MainWindowBase}">
                    <ContentPresenter />                                 
            </ControlTemplate>
        </Setter.Value>
     </Setter>
     </Style>

 public partial class AWindowImplementation :MainWindowBase {

 ... InitializeComponent()

}

 <MainWindowBase x:Class="AWindowImplementation"> </MainWindowBase>

I guess I will have to use different field names in the base class to get rid of the warnings, or perhaps remove InitializeComponent in the derived class. But anyway it works now.

2
  • You are speaking of an override, do you have an abstract method ? Commented Jun 21, 2012 at 14:37
  • no, just fields defined in the abstract class that are defined again in the subclass by the auto-generated InitializeComponent code Commented Jun 21, 2012 at 18:31

3 Answers 3

2

In WPF you can create a Base class which inherits from Window and that has a XAML. But there is a workground

refer this link - How to create a common WPF base window style?

Sign up to request clarification or add additional context in comments.

1 Comment

my base class has no xaml, but each implementation does. thanks will try the link's strategy and if it works come back and accept
0

I'm not sure how you would expect that pseudo-code to work as nothing is calling your InitializeComponent. Ordinarily, WPF calls it on your behalf in your window's constructor. But in your case you're adding a new implementation (not an override) and nothing is calling it.

One option is to just call your new implementation from each subclass constructor. eg. AWindowImplementation's constructor could call this.InitializeComponent().

Another option is for BaseWindow to define a virtual method (say, InitializeComponentCore) that its constructor calls. Base classes can then override that method.

1 Comment

InitializeComponent is already being called in the subclass constructor. that's why i am getting the 'hiding' warning. sorry if the pseudo-code is unclear.
0

You need to define base class for Window as a custom control. Just create a new custom control, set base class to Window and then insert style from blend (you may add yours components). See also answer from pchajer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.