如何让WPF的所有窗口继承一个公共的类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何让WPF的所有窗口继承一个公共的类相关的知识,希望对你有一定的参考价值。

参考技术A 没什么办法,你只能直接新建一个窗口后,将他的父类改成你的公共父类

在 WPF 中指定自定义窗口的默认外观?

【中文标题】在 WPF 中指定自定义窗口的默认外观?【英文标题】:Specifying a custom Window's default appearance in WPF? 【发布时间】:2011-09-29 18:36:49 【问题描述】:

我想为我常用的一些 WPF 控件创建一个库,其中一个控件是 CustomWindow,它继承自 Window 类。如何让我的CustomWindow 使用库中定义的默认外观?

我可以替换

<Window x:Class="..." />

<MyControls:CustomWindow x:Class="..." />

它适用于窗口行为,但不适用于外观。

编辑

这是我目前所拥有的简化版本:

自定义窗口控件。位于控件库中。

public class CustomChromeWindow: Window

    static CustomChromeWindow()
    
        DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomChromeWindow), 
            new FrameworkPropertyMetadata(typeof(CustomChromeWindow)));
     

窗口样式。位于控件库的Themes文件夹中的一个Generic.xaml,一个ResourceDictionary

<Style TargetType="local:CustomChromeWindow">
    <Setter Property="WindowStyle" Value="None" />
    <Setter Property="Background" Value="Red" />
</Style>

测试窗口。引用控件库的单独项目的启动窗口

<local:CustomChromeWindow
    x:Class="MyControlsTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MyControls;assembly=MyControls"
    Title="MainWindow" Height="350" Width="525"
    >
    <Grid>
        <TextBlock Text="This is a Test" />
    </Grid>
</local:CustomChromeWindow>

我最终得到的是一个带有常规 WindowStyle 和黑色背景的窗口。

【问题讨论】:

“外观”是什么意思?你在设置属性吗?添加子元素? @Joe White:两者都有。我正在设置一些属性,例如 WindowStyle、Background、MaxHeight 等,并覆盖模板。新模板有自己的标题栏、最小/最大/关闭按钮、圆形菜单按钮等。 mdm20 的回答对我有用。我有类似的东西,我将文件移动到另一个项目。 VS2012 不会将 ThemeInfo 语句复制到新项目中。 【参考方案1】:

使用这个 xaml:

<Window x:Class="MyNamespace.CustomWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:MyControls="MyNamespace">

    <Window.Style>
        <Style TargetType="MyControls:CustomWindow">
        ...
        </Style>
    </Window.Style>

    <ContentPresenter />

</Window>

您可能想为窗口设计一个新主题。如果是这样,请将以下主题放在(您的库)\Themes\Generic.xaml 资源文件中:

<Style TargetType="x:Type MyControls:CustomWindow">
    <Setter Property="WindowStyle" Value="None" />
    <Setter Property="AllowsTransparency" Value="True" />
    ...

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="x:Type MyControls:CustomWindow">
                <Border>
                    ...
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

【讨论】:

当覆盖窗口主题时,您必须设计一个全新的模板。如果要保留默认模板,请使用第一个 xaml,并使用第二个完全替换它。 将 Window 放在另一个库中的全部目的是避免在每个使用该窗口的应用程序中重写窗口模板。我正在尝试让它现在与 Generic.xaml 文件一起工作,但运气不佳。 请注意,具有 xaml 的窗口不能是另一个窗口的根。因此,您不能例如在 xaml 中更改其样式。为窗口设计新模板允许从基本窗口继承并在 xaml 中更改其属性。 你是对的。要创建自定义窗口模板,我需要完全重新创建窗口对象,包括调整大小和最小/最大/关闭按钮等内容。如果我只是简单地重新设置样式,事情会容易得多,但我也想更改模板。【参考方案2】:

这个怎么样(把这个放在默认的Cctor中):

 DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomWindow)
                                             , new FrameworkPropertyMetadata(typeof(CustomWindow)));`

【讨论】:

它做了一些事情,但不是它应该做的事情。我指定WindowStyle=NoneBackground=Red 进行测试,但我得到的是常规窗口样式,但背景为黑色。 嗯,你能发布你的问题的快速 XAML 模型吗? 你如何加载你的 Generic.xaml 资源字典(有样式)?【参考方案3】:

尝试将其添加到类库中的 AssemblyInfo.cs 文件中

[assembly: ThemeInfo(
    ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
    //(used if a resource is not found in the page, 
    // or application resource dictionaries)
    ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
    //(used if a resource is not found in the page, 
    // app, or any theme specific resource dictionaries)
)]

【讨论】:

以上是关于如何让WPF的所有窗口继承一个公共的类的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript的类

您可以强制从抽象基类继承的类仅具有在基本情况下定义的公共方法吗?

WPF 子窗体 在 父窗体 中 打开,初学不懂,请指教

WPF自学入门WPF自定义窗口基类

wpf自定义控件或窗体继承问题,继承之后出现不能是 XAML 文件的根

如何禁止公共继承但允许私有(和受保护)继承