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();
          }
       };

 

posted @ 2018-09-28 15:44  softwyy  阅读(4650)  评论(2编辑  收藏  举报