當應用程序啓動時,我想讓我的WPF窗口自動捕捉到屏幕的右邊緣。有沒有辦法做到這一點?我也希望能夠保留它的尺寸。因此,與將窗口拖動到屏幕邊緣時發生的捕捉行爲不同,導致窗口調整爲屏幕的一部分或全屏幕時,我希望我的窗口能夠簡單地捕捉到某個位置的邊緣默認情況下,或者如果用戶將其拖動到特定位置,而不調整大小。我仍然希望保留用戶將窗口拖離邊緣的能力。如何在保持其大小的同時自動將WPF窗口捕捉到屏幕邊緣?
有沒有像已經實現的東西,或者我將不得不創建自己的行爲模式?我嘗試了許多搜索關鍵字組合,但找不到類似於我正在做的事情。一些搜索包括禁用捕捉行爲或提供捕捉行爲,但沒有以上述方式。
編輯:
我一直沒能找到一個現成的解決方案,所以我寫了我自己。該解決方案基於BenVlodgi的建議,所以我感謝他幫助我。這是一個非常粗糙的實現,仍然需要大量的拋光和更好的代碼技術,但它的工作原理,並且它是任何人想要嘗試這個的好基礎。它非常簡單,並且與WPF一起工作得非常好。這個實現的唯一限制是我還沒有嘗試讓它在兩個屏幕上工作,但它非常簡單(我只是沒有時間去做,而且現在我不需要這個功能) 。所以,這裏的代碼,我希望它可以幫助別人那裏:
public partial class MainWindow : Window
{
// Get the working area of the screen. It excludes any dockings or toolbars, which
// is exactly what we want.
private System.Drawing.Rectangle screen =
System.Windows.Forms.Screen.PrimaryScreen.WorkingArea;
// This will be the flag for the automatic positioning.
private bool dragging = false;
// The usual initialization routine
public MainWindow()
{
InitializeComponent();
}
// Wait until window is lodaded, but prior to being rendered to set position. This
// is done because prior to being loaded you'll get NaN for this.Height and 0 for
// this.ActualHeight.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// Sets the initial position.
SetInitialWindowPosition();
// Sets the monitoring timer loop.
InitializeWindowPositionMonitoring();
}
// Allows the window to be dragged where the are no other controls present.
// PreviewMouseButton could be used, but then you have to do more work to ensure that if
// you're pressing down on a button, it executes its routine if dragging was not performed.
private void Window_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
// Set the dragging flag to true, so that position would not be reset automatically.
if (e.ChangedButton == System.Windows.Input.MouseButton.Left)
{
dragging = true;
this.DragMove();
}
}
// Similar to MouseDown. We're setting dragging flag to false to allow automatic
// positioning.
private void Window_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (e.ChangedButton == System.Windows.Input.MouseButton.Left)
{
dragging = false;
}
}
// Sets the initial position of the window. I made mine static for now, but later it can
// be modified to be whatever the user chooses in the settings.
private void SetInitialWindowPosition()
{
this.Left = screen.Width - this.Width;
this.Top = screen.Height/2 - this.Height/2;
}
// Setup the monitoring routine that automatically positions the window based on its location
// relative to the working area.
private void InitializeWindowPositionMonitoring()
{
var timer = new System.Windows.Threading.DispatcherTimer();
timer.Tick += delegate
{
// Check if window is being dragged (assuming that mouse down on any portion of the
// window is connected to dragging). This is a fairly safe assumption and held
// true thus far. Even if you're not performing any dragging, then the position
// doesn't change and nothing gets reset. You can add an extra check to see if
// position has changed, but there is no significant performance gain.
// Correct me if I'm wrong, but this is just O(n) execution, where n is the number of
// ticks the mouse has been held down on that window.
if (!dragging)
{
// Checking the left side of the window.
if (this.Left > screen.Width - this.Width)
{
this.Left = screen.Width - this.Width;
}
else if (this.Left < 0)
{
this.Left = 0;
}
// Checking the top of the window.
if (this.Top > screen.Height - this.Height)
{
this.Top = screen.Height - this.Height;
}
else if (this.Top < 0)
{
this.Top = 0;
}
}
};
// Adjust this based on performance and preference. I set mine to 10 milliseconds.
timer.Interval = new TimeSpan(0, 0, 0, 0, 10);
timer.Start();
}
}
確保你的窗口有以下幾點:
MouseDown="Window_MouseDown"
MouseUp="Window_MouseUp"
WindowStartupLocation="Manual"
Loaded="Window_Loaded"
而且,這不適合與Windows本地組件工作窗口的,比如最上面一欄,所以我禁用的風格和創建自己的(這實際上是爲我好,因爲我不希望這樣做的windows風格):
WindowStyle="None"
我用你的解決方案的一部分只是設置初始位置謝謝。不過,我改變了屏幕大小得到例程: private Rect screen = System.Windows.SystemParameters.WorkArea; 擺脫使用表格的需要 – sergeantKK
@sergeantKK感謝您的提示,我會試一試。如果它對你有幫助,不要忘記註冊。 :) –