Microsoft Developer Network > 포럼 홈 > Windows Presentation Foundation (WPF) > Make a Custom Window (inherit from <Window>)
질문하기질문하기
 

답변됨Make a Custom Window (inherit from <Window>)

  • 2006년 11월 17일 금요일 오후 4:29Horst Klein 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     

    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.

     

답변

  • 2006년 12월 7일 목요일 오전 9:12Horst Klein 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     답변됨

    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 

모든 응답

  • 2006년 12월 7일 목요일 오전 9:12Horst Klein 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     답변됨

    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 

  • 2006년 12월 7일 목요일 오후 12:03Zhou Yong 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     
    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
  • 2006년 12월 7일 목요일 오후 1:06Horst Klein 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     

    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

  • 2006년 12월 7일 목요일 오후 2:42Zhou Yong 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     
    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


  • 2007년 6월 23일 토요일 오후 4:22Umit Gunduz 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     

      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

  • 2008년 9월 25일 목요일 오후 5:07Grzegorz Wiśniewski 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     
    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?
  • 2008년 9월 25일 목요일 오후 7:07leblancmeneses 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     
    '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
  • 2008년 9월 25일 목요일 오후 8:30Grzegorz Wiśniewski 사용자 메달사용자 메달사용자 메달사용자 메달사용자 메달
     
    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?