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


    相信很多人使用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();
              }
           };
  • 相关阅读:
    textarea回车在多浏览器兼容问题
    windows server平台移动oracle表空间
    奇妙的英文recreate,reproduce,regenerate也不同
    《Inside the C++ Object Model》笔记(1~7章)
    1.4买书问题C#源码
    C#的Compiler Error CS1660
    数学符号表
    C#工程添加了DLL编译运行时却提示”无法加载DLL“的解决方案
    看源代码那些事【转】
    救命的软件,查看你关掉的网站内容
  • 原文地址:https://www.cnblogs.com/softwyy/p/9719036.html
Copyright © 2020-2023  润新知