当前位置:网站首页>WPF window centering & change trigger mechanism
WPF window centering & change trigger mechanism
2022-06-26 02:23:00 【Dotnet cross platform】
This article is authorized by the original author to share it twice in an original way , Welcome to reprint 、 Share .
Original author : Tang, song, yuan, Ming and Qing Dynasties
Original address :https://www.cnblogs.com/kybs0/p/7420767.html
Center window & Change trigger mechanism
solve :
1) Single instance window , Every time the window is hidden and then displayed , The position is centered
2) Multi screen single instance window , When the parent window moves to another screen , When the single instance window pops up again , The location is updated to the parent window screen .
3) Every time the child window wakes up , It's all centered .
Where the window first appears - WindowStartupLocation
Windows The start-up position of the is displayed ,WindowStartupLocation
CenterOwner-- Display in the middle of the parent window ( Set upOwner)CenterScreen-- Displayed in the middle of the current screenManual-- Default location When the firstWindow.ShowDialogwhen ,windowDisplay the above settings .
Change trigger mechanism The above only covers the first display position , after , The position of the window will remain
How to set the window to pop up again after hiding , Show in the middle (CenterOwner/CenterScreen)? How to set the window to stay in the middle ?
Let's get to know , What are the triggering mechanisms
Activated Window activation When the window changes to the foreground window ( That is, it is displayed in the front ), Will trigger
IsVisibleChanged Show changes When we set the window to hide
Hide() when ,IsVisibile=false. Window againShowDialogwhen ,IsVisibile=true; Using the above two mechanisms , Now we can do something .
First define several enumerations :
/// <summary>
/// The window displays the change trigger time
/// </summary>
public enum WindowLocationInvokeOccasion
{
/// <summary>
/// as long as Activated Just in the middle
/// </summary>
Activated = 0,
/// <summary>
/// Only for the first time Activated when , Show once in the middle , Subsequent changes will not be modified
/// </summary>
FirstActivated,
/// <summary>
/// Every time the window is displayed , Center window
/// <para> It can solve the problem that the pop-up window of a single instance is not centered </para>
/// </summary>
Visibile,
/// <summary>
/// Every time the window is displayed , If the parent window is not on the same screen as the current window , Center window
/// <para> It can solve the problem that the pop-up window of a single instance is not centered </para>
/// </summary>
VisibileInDifferentScreen,
/// <summary>
/// Don't trigger
/// </summary>
Defatult
}The above enumeration contains 4 There's a trigger mechanism .
Let's define an additional attribute , Set additional functions of the window through additional properties - The trigger mechanism is displayed in the center
/// <summary>
/// The window displays the center trigger timing
/// <para> another : Center display settings , Please use <see cref="Window"/> Of <see cref="WindowStartupLocation"/> attribute </para>
/// </summary>
public static readonly DependencyProperty InvokeOccasionProperty = DependencyProperty.RegisterAttached(
"InvokeOccasion", typeof(WindowLocationInvokeOccasion), typeof(WindowLocationOptions),
new PropertyMetadata(default(WindowLocationInvokeOccasion), InvokeOccasionProperty_ChangedCallback));In the property change trigger event , According to different trigger conditions , Set different centered display .
Activated-- as long asActivatedJust in the middle Every time a trigger , Just display the window directly ;For the first time
ActivatedBy settingWindow.Activated -= ShowInCenter_Activated; Disable next trigger entryVisibileVisibileInDifferentScreenWhen the window is displayed , If the parent window is not on the same screen as the current window , Center window . How to determine whether the current child window and the parent window are on the same screen ?
var screen = Screen.FromHandle(new WindowInteropHelper(parentWindow).Handle);
Graphics currentGraphics = Graphics.FromHwnd(new WindowInteropHelper(parentWindow).Handle);
double dpiXRatio = currentGraphics.DpiX / 96;
double dpiYRatio = currentGraphics.DpiY / 96;
// When the child window is on the same screen as the parent window , Do not deal with
var isSubWindowInSameScreen = subWindow.Left > screen.Bounds.Left / dpiXRatio &&
subWindow.Left < screen.Bounds.Left / dpiXRatio + screen.Bounds.Width / dpiXRatio &&
subWindow.Top > screen.Bounds.Top / dpiYRatio &&
subWindow.Top < screen.Bounds.Top / dpiYRatio + screen.Bounds.Height / dpiYRatio;
return isSubWindowInSameScreen;Describe the trigger conditions for completion , Now let's say that the window is centered . centered , It is divided into The current screen is centered / Center in the main window , Go straight to the code
1) Center in the main window -CenterOwner Set the position of the window Location(Left,Top)( top left corner )
When child windows are maximized --
WindowState=“Maximized”Maximization window , Fixed pop-up to the main screen , Therefore, additional treatment is required , According to the screenLocationSet location ;When the parent window is maximized -- When the parent window is maximized , Of the parent window
location, Due to window settingsmargin, It may not be accurate , So take the screen positionCenterOwner The window is centered -- Take the position of the parent window directly / Size and sub window size , Just do the calculation ;
PS: Window locationLeft/TopMay be a negative
/// <summary>
/// Center in the main window
/// </summary>
/// <param name="subWindow"></param>
/// <param name="parentWindow"></param>
private static void SetWindowInCenterOwner(Window subWindow, Window parentWindow)
{
// Maximization window , Fixed pop-up to the main screen , Therefore, additional treatment is required
if (subWindow.WindowState == WindowState.Maximized)
{
// When child windows are maximized , You need to set the position according to the screen ;
var screen = Screen.FromHandle(new WindowInteropHelper(parentWindow).Handle);
Graphics currentGraphics = Graphics.FromHwnd(new WindowInteropHelper(parentWindow).Handle);
double dpiXRatio = currentGraphics.DpiX / 96;
double dpiYRatio = currentGraphics.DpiY / 96;
subWindow.Left = screen.Bounds.Left / dpiXRatio;
subWindow.Top = screen.Bounds.Top / dpiYRatio;
}
if (parentWindow.WindowState == WindowState.Maximized)
{
// When the parent window is maximized , Of the parent window location, Due to window settings margin, It may not be accurate , So take the screen position
var screen = Screen.FromHandle(new WindowInteropHelper(parentWindow).Handle);
Graphics currentGraphics = Graphics.FromHwnd(new WindowInteropHelper(parentWindow).Handle);
double dpiXRatio = currentGraphics.DpiX / 96;
double dpiYRatio = currentGraphics.DpiY / 96;
// The window is centered
subWindow.Left = screen.Bounds.Left / dpiXRatio +
(screen.Bounds.Width / dpiXRatio - subWindow.ActualWidth) / 2;
subWindow.Top = screen.Bounds.Top / dpiYRatio +
(screen.Bounds.Height / dpiYRatio - subWindow.ActualHeight) / 2;
}
else
{
// The window is centered
subWindow.Left = parentWindow.Left + (parentWindow.ActualWidth - subWindow.ActualWidth) / 2;
subWindow.Top = parentWindow.Top + (parentWindow.ActualHeight - subWindow.ActualHeight) / 2;
}
}2) The current screen is centered -CenterScreen;
The window position setting is the same as above , It is worth noting that
DPI.adopt
winDisplay settings for , Adjust the text display scale , Screen position conversion(X,Y)``, We have to think about itDPI` Conversion of ;
/// <summary>
/// Display in the center of the screen where the parent window is located
/// </summary>
/// <param name="subWindow"></param>
/// <param name="parentWindow"></param>
private static void SetWindowInCenterScreen(Window subWindow, Window parentWindow)
{
SetWindowLocationInScreen(subWindow, parentWindow, subWindow.WindowState);
}
private const int DpiPercent = 96;
private static void SetWindowLocationInScreen(Window subWindow, Window parentWindow, WindowState windowState)
{
var intPtr = new WindowInteropHelper(parentWindow).Handle;
var screen = Screen.FromHandle(intPtr);
using (Graphics currentGraphics = Graphics.FromHwnd(intPtr))
{
double dpiXRatio = currentGraphics.DpiX / DpiPercent;
double dpiYRatio = currentGraphics.DpiY / DpiPercent;
if (windowState == WindowState.Maximized)
{
// Set full screen Location
subWindow.Left = screen.Bounds.Left / dpiXRatio;
subWindow.Top = screen.Bounds.Top / dpiYRatio;
}
else
{
// Set center Location
subWindow.Left = screen.Bounds.Left / dpiXRatio +
(screen.Bounds.Width / dpiXRatio - subWindow.ActualWidth) / 2;
subWindow.Top = screen.Bounds.Top / dpiYRatio +
(screen.Bounds.Height / dpiYRatio - subWindow.ActualHeight) / 2;
}
}
}边栏推荐
- @Query 疑难杂症
- Connectez Le projecteur
- How to set an achievable annual goal?
- How do I fix the iPhone green screen problem? Try these solutions
- ROS2+DDS+RTPS
- 创建OpenGl窗口
- Small ball bouncing against the wall
- 表达式的动态解析和计算,Flee用起来真香
- Wechat launched a web version transmission assistant. Is it really easy to use?
- Binary search
猜你喜欢

Eureka注册信息配置备忘

Bloc入门之Cubit详解

One minute to understand the difference between synchronous, asynchronous, blocking and non blocking

Raspberry pie + AWS IOT introductory experiment

Eureka registration information configuration memo

@Query 疑难杂症

vs2015+PCL1.8.1+qt5.12-----(1)

图的深度优先遍历

cv==biaoding---open----cv001

Ardiuno smart mosquito racket
随机推荐
WPF 窗口居中 & 变更触发机制
微博评论的高性能高可用计算架构
将weishi相机图片进行转换
Eureka registration information configuration memo
Interface test case design
Other codes,, VT,,, K
Graphics rendering pipeline
饼图变形记,肝了3000字,收藏就是学会!
Output Lua print to the cocos2d console output window
vtk初始化代码学习1
SQL column value to row value (unpivot)
Largeur d'abord traversée basée sur la matrice de contiguïté
Timer case
Keda 2.7.1 brief analysis of scaledjob code
深度好文:什么是超网 Supernetting?
[untitled] vsbiji ESP thirty-two
基于邻接表的深度优先遍历
How to improve code execution efficiency with arm pipeline
ARM流水线如何提高代码执行效率
# 云原生训练营毕业总结