Arul Murugan.C
Arul Murugan.C

Reputation: 111

creating a common structure(theme) in WPF window

I just created a windows Form application to inherit controls from base form and it works fine.

In WPF XAML is it possible to inherit controls from a base form to another like above?

When I tried in visual studio, I have got an error showing:"'parentchild.MainWindow' cannot be the root of a XAML file because it was defined using XAML".

My Basewindow cs code:

namespace parentchild
    {
    public partial class BaseWindow : Window
        {
            public BaseWindow()
            {
                InitializeComponent();
            }
        }
}

My Basewindow xaml code:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon" x:Class="parentchild.BaseWindow"
        Title="BaseWindow" Height="350" Width="525">
    <Grid>
        <StatusBar HorizontalAlignment="Left" Height="35" Margin="0,285,0,0" VerticalAlignment="Top" Width="517">
            <Label Content="Label"/>
            <Label Content="Label"/>
        </StatusBar>
    </Grid>
</Window>

My childwindow cs code:

namespace parentchild
{
    public partial class childwindow : BaseWindow
    {
        public childwindow()
        {
            InitializeComponent();
        }
    }
}

My childwindow xaml code:

   <mn:BaseWindow x:Class="parentchild.childwindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mn="clr-namespace:parentchild"
            Title="childwindow" Height="300" Width="300">
        <Grid>

        </Grid>
    </mn:BaseWindow>

I found another solution by creating an user control and applying it to all windows.Is that the right way?

Or anybody have solution for creating a general theme/structure for all Xaml windows.

Please provide me a solution to solve this issue.

Upvotes: 0

Views: 651

Answers (2)

Xavier
Xavier

Reputation: 3404

It looks like you are basically trying to create a custom control that extends Window. Creating custom controls in WPF is a complex topic because there is a lot to consider when deciding how to implement one. Take a look at this article that talks about this:

Control Authoring Overview

Most likely, you do not actually want a custom control, but rather a custom ControlTemplate (authored in xaml) that redefines how you want your window to look. You can define the template in a Style and apply that style to any Window that you want. It is a lot to try to explain here in an answer, so you should read up on how control templates work and how they are useful.

If you decide you need to add new properties to your custom window, then you will want to make a new class that extends Window and adds those properties as dependency properties (now you have a custom control). You can then use those properties in your custom ControlTemplate to do whatever you want them to do.

Working in WPF is not at all like working in Windows Forms. If you try to apply techniques and practices you learned in Windows Forms to a WPF application, you will cause yourself a lot of headaches. I made that transition a couple years ago, and my advice is to make no assumptions about WPF based on what you know from Windows Forms. They are completely different systems with different ways of doing things.

Upvotes: 0

MisterXero
MisterXero

Reputation: 1128

You cannot inherit from a class that has been defined in xaml. I would probably go with creating a UserControl and using that as a 'base container' in any Window you want to have the status bar. If you are intent on making a base Window you could try something like this:

Define the base Window in code only:

public class MyWindowBase : Window
    {
        private ContentControl contentControl;

        public MyWindowBase()
        {
            this.CreateContent();
        }

        public Object BaseContent
        {
            get { return this.contentControl.Content; }
            set { this.contentControl.Content = value; }
        }

        private void CreateContent()
        {
            var grid = new Grid();
            var row1 = new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) };
            var row2 = new RowDefinition() { Height = GridLength.Auto };
            grid.RowDefinitions.Add(row1);
            grid.RowDefinitions.Add(row2);

            var statusBar = new StatusBar() { Height = 35, Background = Brushes.Blue }; // Initialize the status bar how you want.
            Grid.SetRow(statusBar, 1);

            this.contentControl = new ContentControl();

            grid.Children.Add(this.contentControl);
            grid.Children.Add(statusBar);

            base.Content = grid;
        }
    }

Use the base window in xaml like this:

<WpfApplication7:MyWindowBase xmlns:WpfApplication7="clr-namespace:WpfApplication7"  x:Class="WpfApplication7.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="500">
    <WpfApplication7:MyWindowBase.BaseContent>
        <Button>
            Something
        </Button>
    </WpfApplication7:MyWindowBase.BaseContent>    
</WpfApplication7:MyWindowBase> 

Of course the base class has room for improvement, like making BaseContent a dependency property, but I think it demonstrates the main idea.

Upvotes: 1

Related Questions