locked
Make a Custom Window (inherit from <Window>) RRS feed

  • Question

  • How can I make a custom Window?

    I want build a custom Windows to give him custom Properties.

    And make based on myCustomWindow other CustomWindows.

    And this Windows shold be visible in the FormsDesigner.

     

    Friday, November 17, 2006 4:29 PM

Answers

  • The answer to my support request to Microsoft:

    Xaml does not support visual inheritance.  Xaml provides the complete element tree for a class, and there is no defined way to merge two trees together.  I also don’t think I’d use templating for this.  I think instead I would use user controls and create a control that defined the common parts of the Window and use that control on every subsequent window.  I managed to make this work.  I created a “WindowSurface” control that derived from UserControl.  It has the following XAML and code:

     

    <UserControl 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="CiderWindowsApplication31.WindowSurface" FlowDirection="RightToLeft" >
       <DockPanel LastChildFill="True">
        <StackPanel   DockPanel.Dock="Bottom" Orientation="Horizontal">
          <Button>Cancel</Button>
          <Button>OK</Button>
        </StackPanel>
        <ContentControl Name="surfaceContent"></ContentControl>
      </DockPanel>
    </UserControl>

    using System;
    using System.ComponentModel;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Input;
    using System.Windows.Documents;
    using System.Windows.Media;
    using System.Windows.Shapes;
    using System.Windows.Markup; 

    namespace CiderWindowsApplication31 {

        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>

        [ContentProperty("SurfaceContent")]
        public partial class WindowSurface : UserControl {

            public WindowSurface()
                : base() {
                InitializeComponent();
            }

            public object SurfaceContent {
                get { return surfaceContent.Content; }
                set { surfaceContent.Content = value ; }
            }
        }
    }

    Next, I placed this control on a Window like this:

    <Window 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:l="clr-namespace:CiderWindowsApplication31" 
      x:Class="CiderWindowsApplication31.Window1"
      Title="Main Window">
      <l:WindowSurface>
        <Grid>
          <Button Margin="143,102,55,111" Name="button1"  >Button</Button>
        </Grid>
      </l:WindowSurface>
    </Window>

    Once I did this, I can add controls to the “surface” area of the user control 

    Thursday, December 7, 2006 9:12 AM

All replies

  • The answer to my support request to Microsoft:

    Xaml does not support visual inheritance.  Xaml provides the complete element tree for a class, and there is no defined way to merge two trees together.  I also don’t think I’d use templating for this.  I think instead I would use user controls and create a control that defined the common parts of the Window and use that control on every subsequent window.  I managed to make this work.  I created a “WindowSurface” control that derived from UserControl.  It has the following XAML and code:

     

    <UserControl 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      x:Class="CiderWindowsApplication31.WindowSurface" FlowDirection="RightToLeft" >
       <DockPanel LastChildFill="True">
        <StackPanel   DockPanel.Dock="Bottom" Orientation="Horizontal">
          <Button>Cancel</Button>
          <Button>OK</Button>
        </StackPanel>
        <ContentControl Name="surfaceContent"></ContentControl>
      </DockPanel>
    </UserControl>

    using System;
    using System.ComponentModel;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Input;
    using System.Windows.Documents;
    using System.Windows.Media;
    using System.Windows.Shapes;
    using System.Windows.Markup; 

    namespace CiderWindowsApplication31 {

        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>

        [ContentProperty("SurfaceContent")]
        public partial class WindowSurface : UserControl {

            public WindowSurface()
                : base() {
                InitializeComponent();
            }

            public object SurfaceContent {
                get { return surfaceContent.Content; }
                set { surfaceContent.Content = value ; }
            }
        }
    }

    Next, I placed this control on a Window like this:

    <Window 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:l="clr-namespace:CiderWindowsApplication31" 
      x:Class="CiderWindowsApplication31.Window1"
      Title="Main Window">
      <l:WindowSurface>
        <Grid>
          <Button Margin="143,102,55,111" Name="button1"  >Button</Button>
        </Grid>
      </l:WindowSurface>
    </Window>

    Once I did this, I can add controls to the “surface” area of the user control 

    Thursday, December 7, 2006 9:12 AM
  • I think you just introduce an extra complexity to the UserControl by adding the "SurfaceContent" property, why not directly use Content property instead.
    And what do you mean by "Xaml does not support visual inheritance"?

    Sheva
    Thursday, December 7, 2006 12:03 PM
  • I use VS2005 SP1 + WPF-Extensions and have developed following Window...

    <Window x:Class="VitoWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Custom Window" Height="327" Width="546"
        >
        <Grid>        
        </Grid>
    </Window>

    In another Window I wants to “inherit” this Window (and some other XAML-Controls like a button)...

    <v:VitoWindow
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:v="clr-namespace:CustomControlLibrary;assembly=CustomControlLibrary"
          xml:lang="de-DE" x:Class="Window1" x:Name="Window" Title="VitoWindow"
          Width="640" Height="480"
         
    xmlns:d=http://schemas.microsoft.com/expression/blend/2006
          mlns:mc
    =http://schemas.openxmlformats.org/markup-compatibility/2006
         
    mc:Ignorable="d">
         <Grid x:Name="LayoutRoot">
                <Grid.ColumnDefinitions>
                     <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <v:VitoButton Margin="138.288,62,315.712,0" VerticalAlignment="Top" Height="54" Content="VitoButton" d:LayoutOverrides="HorizontalAlignment"/>
          </Grid>
    </v:VitoWindow>

    ...but he gets... 

    Warning           1          'CustomControlLibrary.VitoWindow' cannot be the root of a XAML file because it was defined using XAML. Line 2 Position 2. Window1.xaml  2          2            CustomWindow

    And THIS is not supported in XAML! 

    I tried on this way to give the Original Window some Custom Properties and Methods

    Horst

    Thursday, December 7, 2006 1:06 PM
  • For current bit of WPF, you cannot subclass from xaml generated class, but you can work around this by doing something like the following:
    First off, create an custom WPF control library project, and then declare your custom window this way:
    namespace CustomControlLib
    {
        public class CustomWindow : Window
        {
            static CustomWindow()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomWindow), new FrameworkPropertyMetadata(typeof(CustomWindow)));
            }
     
        }
    }

    In the Themes\generic.xaml file:
    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:cc ="clr-namespace:CustomControlLib"
        >
      <Style TargetType="{x:Type cc:CustomWindow}">
        <Setter Property="AllowsTransparency" Value="True"/>
        <Setter Property="WindowStyle" Value="None"/>
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="{x:Type cc:CustomWindow}">
              <Border BorderBrush="Green" BorderThickness="1" CornerRadius="10">
                <AdornerDecorator>
                  <ContentPresenter
                     ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
                     Content="{TemplateBinding ContentControl.Content}" />
                </AdornerDecorator>
              </Border>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style>
    </ResourceDictionary>

    Then you can optionally do something like this in the AssemblyInfo.cs:
    [assembly: XmlnsDefinition("http://schemas.sheva.com/winfx/2006/xaml/presentation", "CustomControlLib")]

    Lastly, create a WPF application project, and declare the window this way:

    <cc:CustomWindow x:Class="CustomWindowDemo.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:cc="http://schemas.sheva.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="CustomWindowDemo" Height="300" Width="300"
        >
      <Grid>
        <Button Content="This is a custom window" Margin="5"/>
      </Grid>
    </cc:CustomWindow>

    Just compile and run this, it works perfectly. and you can actually specify additional DPs to your CustomWindow class.

    Sheva


    Thursday, December 7, 2006 2:42 PM
  •   Zhou Yong this inheritance method is ok. Already i use to this method but my problem that,

     

    I have an example BasePage, BrowseBasePage, and SearcherBrowseBasePage. These is my framework pages

     

    BrowseBasePage inherit BasePage and SearcherBrowseBasePage inherit BrowseBasePage

     

    after than i create a new page is MyBrowsePage and this page inherit SearcherBrowseBasePage

     

    i can code behind inheritance. But i can't visual inheritance although use Zhou Yong's visual inheritance method

     

    Can i do this inheritance.

     

    can you help me? 

     

    Thanks

    Saturday, June 23, 2007 4:22 PM
  • Zhou Yong I have a question. In Class library Dolphin.Windows.dll I have declare class:

    namespace Dolphin.Windows
    {
        public class Window : System.Windows.Window
        {
            public Window():base()
            {
            }
        }
    }

    In this project in AssemblyInfo.cs I have:

    [assembly: System.Windows.Markup.XmlnsDefinition("http://schemas.mk-system.pl/winfx/2006/xaml/presentation", "Dolphin.Windows")]

    I want using Dolphin.Windows.Window in project Mirage. In Main.xaml.cs I set:

    namespace Mirage.Main
    {
        public partial class WinMain : Dolphin.Windows.Window
        {
            public WinMain()
            {
                InitializeComponent();
            }
        }
    }

    And in Main.xaml"

    <dolphin:Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Class="Mirage.Main.WinMain"
        xmlns:dolphin="http://schemas.mk-system.pl/winfx/2006/xaml/presentation"
        Title="Mirage"
        Width="800"
        Height="600"
        MinWidth="800"
        MinHeight="600"
        >
    </dolphin:Window>

    When I compile project I have error:

    Error    1    Invalid XmlnsDeclaration occurs in assembly 'Mirage, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'. XmlnsDeclaration references a namespace 'Dolphin.Windows' that is not in the assembly.    D:\Application C#\Mirage\Mirage\Main\WinMain.xaml    1    1    Mirage

    And:

    Error    2    The type 'dolphin:Window' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.    D:\Application C#\Mirage\Mirage\Main\WinMain.xaml    1    2    Mirage

    What is wrong?
    Thursday, September 25, 2008 5:07 PM
  • 'Dolphin.Windows' that is not in the assembly.

    i think its looking in the wrong location.

    xmlns:dolphin="http://schemas.mk-system.pl/winfx/2006/xaml/presentation"
    should be:
    xmlns:dolphin="clr-namespace:Dolphin.Windows;assembly=Dolphin.Windows"

    <dolphin:Window  will now work.
    x:Class="Mirage.Main.WinMain"  should reference your partial class the xaml will inherit from.




    leblanc
    Thursday, September 25, 2008 7:07 PM
  • When I instal VS C# 2008 SP 1 I have error in xaml file, when I use:
    xmlns:dolphin="clr-namespace:Dolphin.Windows;assembly=Dolphin.Windows"

    Project compile OK, but in designer i have error. When I project run in computer where is not SP 1 project compile OK and designer work OK. I think this error is in computer where is SP 1.

    This is a bug in SP 1?
    Thursday, September 25, 2008 8:30 PM
  • the answer sent by Horst Klein (got it from MS support request reply if I understand correctly) seems to work fine with Visual Studio 2010 XAML designer for Silverlight 5 too

    combined with the visual inheritance approach explained at:
    http://geekswithblogs.net/lbugnion/archive/2007/03/02/107747.aspx
    http://weblogs.asp.net/psheriff/archive/2009/11/02/creating-a-base-window-class-in-wpf.aspx
    and maybe best at http://hardcodedblog.blogspot.gr/2009/12/making-custom-windows-in-wpf.html



    • Edited by ClipFlair Thursday, June 28, 2012 3:53 PM
    • Proposed as answer by ClipFlair Thursday, June 28, 2012 3:53 PM
    Thursday, June 28, 2012 3:51 PM