Make a Custom Window (inherit from <Window>)
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.
答案
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
全部回复
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
- 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 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
- 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 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
- 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?
- '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 - 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?

