none
继承一个wpf窗体的正确步骤是什么 RRS feed

  • 问题

  • 编写了一个基类窗体,去掉默认标题栏,写上自己的标题栏和相关事件,然后进行所谓的继承,把wpf窗体的继承类改为Window改为BaseWindow

    在xaml的头部,把Window换成 <基础窗体类的命令空间:BaseWindow,

    加上这一句  xmlns:基础窗体类的命令空间="clr-namespace:基础窗体类的命令空间"

    然后出现了2个错误

      “继承基础窗体的新窗体类名”的分部声明一定不能指定不同的基类   

    “基础窗体类的命令空间.BaseWindow”不能是 XAML 文件的根,因为它是使用 XAML 定义的。

    这要怎么解决?



    • 已编辑 Trian555 2018年12月8日 6:11
    2018年12月8日 6:09

答案

  • 第一個問題是因為後置程式碼的繼承沒有從 Window 改成 BaseWindow 造成,因為 xaml 和 C# code 中指定的基類不匹配。

    第二個問題是 WPF 並不像 Windows Forms 一樣具有可視化繼承 (Visual Inheritance),所以目前不支援這樣的做法

    所以必須要換個方式做

    第一種: 不使用 xaml,完全只使用 c# code 定義 BaseWindow

    第二種: 使用 xaml 的方式,步驟如下述

    (1) 使用自定義控件範本 (Custom Control Template), 比方你使用 BaseWindow 這名稱建立,這時會看到兩個檔案 (a) BaseWindow.cs (b) 在 Themes 目錄下會看到 Generic.xaml

    (2) 將 BaseWindow.cs 中 BaseWindow 的基類由 Control 改為 Window,並添加其他的程式碼(例如你要加入的事件)

     public class BaseWindow : Window 
        {
            static BaseWindow()
            {
                DefaultStyleKeyProperty.OverrideMetadata(typeof(BaseWindow), new FrameworkPropertyMetadata(typeof(BaseWindow)));
            }
        }


    (3) 修改 Generic.xaml, 範例如下 (這和原來默認的 Window 所使用的範本和樣式只差在 TargetType,和多了一個 Title 的Style Setter  )

     <ControlTemplate x:Key="BaseWindowTemplateKey" TargetType="{x:Type local:BaseWindow}">
            <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                <Grid>
                    <AdornerDecorator>
                        <ContentPresenter/>
                    </AdornerDecorator>
                    <ResizeGrip x:Name="WindowResizeGrip" HorizontalAlignment="Right" IsTabStop="false"
                                Visibility="Collapsed" VerticalAlignment="Bottom"/>
                </Grid>
            </Border>
            <ControlTemplate.Triggers>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="ResizeMode" Value="CanResizeWithGrip"/>
                        <Condition Property="WindowState" Value="Normal"/>
                    </MultiTrigger.Conditions>
                    <Setter Property="Visibility" TargetName="WindowResizeGrip" Value="Visible"/>
                </MultiTrigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
        <Style TargetType="{x:Type local:BaseWindow}">
            <Setter Property="Title" Value="MyBase Window"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
            <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:BaseWindow}">
                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                            <AdornerDecorator>
                                <ContentPresenter/>
                            </AdornerDecorator>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="ResizeMode" Value="CanResizeWithGrip">
                    <Setter Property="Template" Value="{StaticResource BaseWindowTemplateKey}"/>
                </Trigger>
            </Style.Triggers>
        </Style>

    (4) 新增一個 Window 並且修改 xaml 中的根元素與C# Code 中的基類

    <local:BaseWindow x:Class="WindowInheritSample.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WindowInheritSample"
            mc:Ignorable="d"
            Height="450" Width="800">
        <Grid>
            
        </Grid>
    </local:BaseWindow>

        public partial class Window1 : BaseWindow 
        {
            public Window1()
            {
                InitializeComponent();
            }
        }

    這樣就可以了。


    在現實生活中,你和誰在一起的確很重要,甚至能改變你的成長軌跡,決定你的人生成敗。 和什麼樣的人在一起,就會有什麼樣的人生。 和勤奮的人在一起,你不會懶惰; 和積極的人在一起,你不會消沈; 與智者同行,你會不同凡響; 與高人為伍,你能登上巔峰。 https://skilltree.my/

    2018年12月9日 22:19