WPF中鼠标事件MouseLeftButtonDown,MouseLeftButtonUp实现无边框窗体的最大化,还原
最近在工作中,开始边学WPF,边在工作中应用。
在做一个自定义边框的WPF窗体的时候,想要实现无边框窗体的:双击标题栏最大化/还原,拖动标题栏移动窗体,拖动标题栏移动到屏幕顶端最大化,在窗体最大化时拖动标题栏恢复窗体原始尺寸。
这个效果在WPF自带边框的前提下,不需要我们去实现,在Window类中已经帮我们做好了。
可是现在我去掉了WPF窗体自带的边框,自己用控件做了一个标题栏和最大化、最小化、关闭按钮,上述的交互效果就要自己实现一下了。
一开始的思路:在作为标题栏的TextBlock控件中,添加MouseDown事件,在这个事件中,处理双击和拖拽交互。然后添加一个MouseLeftButtonUp事件,在这个事件中,处理松开鼠标时,窗体的位置和尺寸。
private void Lb_AppTitle_MouseDown(object sender, MouseButtonEventArgs e)
{ if (e.ClickCount == 2) { if (this.ActualWidth == SystemParameters.WorkArea.Width) { Btn_MaxSize_Clicked(null, null); } else { Btn_MaxSize_Clicked(null, null); } } }
上面代码是处理【双击标题栏,最大化窗体,或者还原窗体】的交互逻辑。
然后在上面代码的基础上,又添加了拖拽交互
private void Lb_AppTitle_MouseDown(object sender, MouseButtonEventArgs e) { if (e.ClickCount == 2) { if (this.ActualWidth == SystemParameters.WorkArea.Width) { Btn_MaxSize_Clicked(null, null); } else { Btn_MaxSize_Clicked(null, null); } } this.DragMove();
}
然后就是在MouseLeftButtonUp事件中,添加鼠标左键抬起后的窗体交互逻辑
private void Lb_AppTitle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (this.Top <= 0) { CurrentWindowState = WindowState.Maximized; 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; } }
但是神奇的事情发生了:MouseLeftButtonUp事件竟然无法触发
然后,在其他TextBlock控件中,添加了一个MouseLeftButtonUp事件,发现是可以触发的。
所以,肯定是之前TextBlock控件中的其他属性或者事件影响到了它的MouseLeftButtonUp事件的触发。
于是,就开始简单粗暴的删除之前TextBlock控件上的属性和事件,一开始,直接删除了MouseDown事件,发现该控件的MouseLeftButtonUp事件竟然可以触发了,
那么,肯定就是MouseDown事件中的代码影响到了MouseLeftButtonUp事件的触发。
最后,发现是拖拽代码DragMove();影响了MouseLeftButtonUp事件的触发。
DragMove();为阻塞方法,在该事件中已经有鼠标按键抬起事件的响应,所以会屏蔽掉外部的鼠标按键抬起事件的触发。
既然如此,那么,就不需要外部的MouseLeftButtonUp事件了。原本该事件存在的目的就是鼠标拖拽窗体结束后,通过检查窗体位置是否在屏幕最顶部,来判断是否最大化窗体。
现在DragMove();方法中,已经有了响应鼠标按键抬起,那么当这个阻塞方法结束后,就意味着鼠标按键已经抬起,那么,我可以将原来的鼠标按键抬起事件中的处理,挪到DragMove();方法之后,就可以起到相同目的。
private void Lb_AppTitle_MouseDown(object sender, MouseButtonEventArgs e) { if (e.ClickCount == 2) { if (this.ActualWidth == SystemParameters.WorkArea.Width) { Btn_MaxSize_Clicked(null, null); } else { Btn_MaxSize_Clicked(null, null); } } else { if (CurrentWindowState == WindowState.Maximized) { CurrentWindowState = WindowState.Normal; this.Left = rcnormal.Left; this.Top = e.GetPosition(this).Y;//rcnormal.Top; this.Width = rcnormal.Width; this.Height = rcnormal.Height; this.Btn_MaxSize.Text = "\uE922"; } this.DragMove(); if (this.Top <= 0) { CurrentWindowState = WindowState.Maximized; 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; this.Btn_MaxSize.Text = "\uE923"; } } }
至此结束!