Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 694|回复: 0

wpf 自定义窗口,最大化时覆盖任务栏解决方案

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-5-10 15:11:38 | 显示全部楼层 |阅读模式

    相信很多人使用wpf时会选择自定义美观的窗口,因此会设置WindowStyle="None" 取消自带的标题栏。但这样使用 WindowState="Maximized" 或者后台 this.WindowState = System.Windows.WindowState.Maximized; 最大化窗口会覆盖掉系统任务栏,即全屏了。这其实并不是个很好的体验。

    在网上找答案,排名靠前的都是提供用hook钩子,篇幅很长,如:http://www.cnblogs.com/zhouyinhui/archive/2008/11/04/1326188.html

    个人感觉这么一个小功能添加那么多的代码是不人性的,于是继续寻找,终于看到黎明的曙光:

    Rect rcnormal;//定义一个全局rect记录还原状态下窗口的位置和大小。
            /// <summary>
            /// 最大化
            /// </summary>
            private void btnMaximize_Click(object sender, RoutedEventArgs e)
            {
                this.btnMaximize.Visibility = Visibility.Collapsed;
                this.btnNormal.Visibility = Visibility.Visible;
                rcnormal = new Rect(this.Left, this.Top, this.Width, this.Height);//保存下当前位置与大小
                this.Left = 0;//设置位置
                this.Top = 0;            
                Rect rc = SystemParameters.WorkArea;//获取工作区大小
                this.Width = rc.Width;
                this.Height = rc.Height;
            }
            /// <summary>
            /// 还原
            /// </summary>
            private void btnNormal_Click(object sender, RoutedEventArgs e)
            {
                this.Left = rcnormal.Left;
                this.Top = rcnormal.Top;
                this.Width = rcnormal.Width;
                this.Height = rcnormal.Height;
                this.btnMaximize.Visibility = Visibility.Visible;
                this.btnNormal.Visibility = Visibility.Collapsed;
            }

    好了,最大化和最小化事件自定义好了。那如果窗口拖动到顶端鼠标出界的话窗口将会最大化是不是?在wpf中 WindowStyle="None" 下也还是全屏效果,而且会覆盖掉我们自定义的效果,这个时候你的this.width和this.height都无用了。那该怎么办呢?看下边:

    在前台添加:

    SizeChanged="Window_SizeChanged"

    后台:

    private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
            {
                if (this.ActualHeight > SystemParameters.WorkArea.Height || this.ActualWidth > SystemParameters.WorkArea.Width)
                {
                    this.WindowState = System.Windows.WindowState.Normal;
                    btnMaximize_Click(null, null);
                }
            }

    或者在最大化后禁用拖动功能,待恢复原始窗口后在恢复拖动功能也可以。

    ok,搞定! 这么简单的代码,相信大家看的懂吧~~

    另附双击标题栏事件:

    private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
            {
                if (e.ClickCount == 2)
                {
                    if (this.ActualWidth == SystemParameters.WorkArea.Width)
                    {
                        btnNormal_Click(null, null);
                    }
                    else
                    {
                        btnMaximize_Click(null, null);
                    }
                }
            }

    最后总结代码:

     Rect rcnormal;
            protected virtual void InitializeEvent()
            {
                ControlTemplate baseWindowTemplate = (ControlTemplate)Application.Current.Resources["BaseWindowControlTemplate"];
    
                TextBlock title = (TextBlock)baseWindowTemplate.FindName("lab_title", this);
                title.Text = window_title;
                title.Margin = mrg;
                Button maxBtn = (Button)baseWindowTemplate.FindName("btnMax", this);
                maxBtn.Visibility = btn_max;
                bool tag = true;
                maxBtn.Click += delegate
                {
                    if (tag)
                    {
                        tag = false;
                        rcnormal = new Rect(this.Left, this.Top, this.Width, this.Height);
                        this.Left = 0;
                        this.Top = 0;
                        Rect rc = SystemParameters.WorkArea;
                        this.Width = rc.Width;
                        this.Height = rc.Height;
                        maxBtn.Style = (Style)Application.Current.Resources["btn_max2"];
                    }
                    else
                    {
                        tag = true;
                        this.Left = rcnormal.Left;
                        this.Top = rcnormal.Top;
                        this.Width = rcnormal.Width;
                        this.Height = rcnormal.Height;
                        maxBtn.Style = (Style)Application.Current.Resources["btn_max"];
                    }
                };
    
                Button closeBtn = (Button)baseWindowTemplate.FindName("btnClose", this);
                closeBtn.Click += delegate
                {
                    this.Close();
                };
                //拖动
                Border borderTitle = (Border)baseWindowTemplate.FindName("borderTitle", this);
                borderTitle.MouseMove += delegate(object sender, MouseEventArgs e)
                {
    //
    tag==true 只有窗口恢复到原始窗口后才可拖动
              if (e.LeftButton == MouseButtonState.Pressed && tag==true) {
                this.DragMove();
              }
           };

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-18 15:02 , Processed in 0.061698 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表