zoukankan      html  css  js  c++  java
  • WPF 实现完全可控制的漂亮自定义窗口

    在WPF界面开发中,有时候不想用系统的死板的窗口,想要来点新花样,常会自定义窗口。

    那么,先抛出问题,想搞出下面这样的窗口,该咋整 ?

    a

     下面看一个啥也没设置过的普通窗口,这样的窗口,我们只能控制客户区,也就是白色部分,标题的棕色部分长啥样,我们控制不了。

     

    所以我们要做的就是把窗口的棕色部分,也整成我们想写啥就写啥。下面放上我实现的效果,源码  https://files.cnblogs.com/files/CSSZBB/CustomWndow.rar

     下面娓娓道来,一个窗口大概需要实现的功能如下

     

    太久远的年代的做法我们就不讨论了,

    现在随便一搜,应该有文章都会说用WindowChrome,如果没有windowchrome,上述的所有功能都需要自己实现,光是拖动边框改变大小这么一个,就够写半天的啦。

    先说坑把,

    1 主要就是最大化的逻辑,使用WindowChrome后最大化有点问题需要特殊处理,且受windowstyle="None"  ResizeMode="NoResize"  这些参数的影响,最大化的效果也不同,需要注意。

    2 在 captionHeight 的范围内的控件,需设置WindowChrome.IsHitTestVisibleInChrome="True" 这个附加属性,

    另外说一下windowstyle="None" 这个参数,按我目前试过的经验来说,除非需要制作能透明的窗口,否则是不需要设置windowstyle="None" 的 ,windowstyle="None" 时,系统自带的最大化,最小化,关闭 三个按钮,都是没有的,需要自己去实现。

     当你给窗口设置了WindowChrome后,

        <Window.Style>
            <Style TargetType="Window">
                <Setter Property="WindowChrome.WindowChrome">
                    <Setter.Value>
                        <WindowChrome CornerRadius="0"
                 CaptionHeight="30" GlassFrameThickness="-1" UseAeroCaptionButtons="True" NonClientFrameEdges="None" /> </Setter.Value> </Setter> </Style> </Window.Style>

      

    先不改window的style的其他参数。看到棕色的部分没有了,就是说设置了WindowChrome后,我们可控制的区域,扩展了本来不能控制的棕色头部

    那么,是否系统给我们生成的棕色部分,没有了那?其他它还是在的,只是被我们的白色部分覆盖了。这里修改一下window的Template 。可以看到它又露出来了

                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate  TargetType="Window">
                            <Grid  >
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="32"/>
                                    <RowDefinition Height="*"/>
                                </Grid.RowDefinitions>
                                <Grid x:Name="Content_Panel" Grid.Row="1" Background="{TemplateBinding Background}">
                                    <AdornerDecorator>
                                        <ContentPresenter/>
                                    </AdornerDecorator>
                                </Grid>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
    

     上面的代码中,我们给Window的模板,定义了一个32高度的行,这个行里啥也不放,也就是透明的。可以看到,系统给生成的最大化,最小化等按钮它又出来了,但是标题,ICO等就没有了。说明标题和ICON ,需要在Template中定义,它不是系统生成的。

    那么,上面指出观察到的这个情况,有何意义那?

    意义可能就是,有时候,我们只是想在标题栏(棕色部分) 添加几个控件,比如加个公司图标啊啥的,而不想改变其它时,可以这样做。这样,可以给我们省下自己去重写最大化,最小化,关闭按钮的时间

     这里面忘记说了窗口重写Style的一个不算坑的坑,在编码阶段,不管你怎么设置Style,标题部分都是不变的,我一度以为是自己写的Style无效,一运行才发现是有效的

    更多的时候,我们希望完全重写棕色部分。如下是一个框架的Window给我们提供的所有功能(包括边框拖动改变大小,按住标题区拖动改变位置),那么我们重写Style Template后,需要自己实现哪些部分那?

    据我的经验,需要自己实现图标,标题,最小化,最大化,关闭这5个部分,

    在没有WindowChrome的年代,重写window是需要自己实现所有功能的,所以说windowchrome还是提供了一些方便的。

    来看下它的属性, 1 CaptionHeight 这个属性,是控制标题区(棕色部分,设置windowchrome后它不显示),接收鼠标响应的高度。  本来它现实的时候,这个部分右键,会弹出系统菜单,按住拖动,双击等都有响应的逻辑

     现在棕色部分虽然不显示了,但是设置了CaptionHeight 后,相应高度的部分,仍然会对支持上述操作。

    它也导致了一个问题,就是当你放上你自己写的最大化,最小化,关闭按钮时,你会发现点击无效,点这些按钮还是触发的 点击标题栏的事件。

    这就牵扯出另外一个属性

    WindowChrome.IsHitTestVisibleInChrome="True"。给你自己写的最大化,最小化,关闭按钮时,加上这个附加属性,他们就能响应鼠标了

     到此,自定义标题栏,应该没啥问题了,你想加啥控件就加啥,完全自由。

     其他属性影响不大

    那么该说说里面的坑了,当你点击最大化窗口时,你会发现它的最大化是有问题的。如下图对比,最大化前,可以看到窗口里的3层的绿色边框,最大化后,发现左右下都只能看到一层边框了。且最大化等按钮,也超出了屏幕导致没显示全。

    如果你设置了windows 的属性ResizeMode="NoResize",或者WindowStyle="None" 你会发现最大化后,它把任务栏也给占了,就想真正的全屏游戏一样!!

     这里的原因想想也不难理解,最大化窗口,你自己实现最大化按钮一般只用设置WindowState = WindowState.Maximized;(不管是直接设置属性还是用系统命令)

    而系统去做最大化这一步,其实是要很多步骤的,包括获取屏幕大小,计算窗口边框,调整窗口大小到屏幕大小(这里要去掉任务栏高度,去掉边框宽度)等等,

    那么当你通过windowchrome重写了windowstyle改变了客户区的大小,系统默认给你的窗口边框边框也变了,它如果还是按原来的处理方式最大化,应该是有问题的。

    这里的更精确的原理我们猜也猜不明白,也不是我们能控制的。只要能根据现在的现象调整出对的结果就行了

    我直接说结果就是最大化时,系统把整个界面多最大化了8。上下左右都是。所以我们设置一个触发器,在最大化的时候,把我们自己定义的区域,缩小8就行了

    完美!!

    剩下的,就是把窗口做的漂亮点啦。开搞把!

  • 相关阅读:
    Java数据结构与算法(24)
    urllib2使用总结
    Python常见文件操作的函数示例
    Java数据结构与算法(23)
    python代码风格检查工具──pylint
    Python抓取框架:Scrapy的架构
    Java数据结构与算法(22)
    【codeforces 431D】Random Task
    【codeforces 449C】Jzzhu and Apples
    【codeforces 20B】Equation
  • 原文地址:https://www.cnblogs.com/CSSZBB/p/14110388.html
Copyright © 2011-2022 走看看