日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

WPF 窗口居中 变更触发机制

發布時間:2025/6/17 asp.net 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WPF 窗口居中 变更触发机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原文:WPF 窗口居中 & 變更觸發機制

窗口居中 & 變更觸發機制

解決:

1。單實例窗口,窗口每次隱藏后再顯示時,位置居中顯示

2。多屏幕下單實例窗口,當父窗口移動到其它屏幕時,單實例窗口再次彈出時,位置才更新到父窗口屏幕。

3。子窗口每次喚醒時,都居中顯示。

窗口首次顯示的位置 - WindowStartupLocation

windows的啟動時位置顯示,WindowStartupLocation

  • CenterOwner --顯示在父窗口的中間(設置Owner)
  • CenterScreen --顯示在當前屏幕中間
  • Manual --默認位置

當第一次window.ShowDialog時,window顯示如上設置。

變更觸發機制

上面只涉及到了首次顯示位置,之后,窗口的位置會繼續保留

  • 如何設置窗口隱藏之后再次彈出時,顯示在中間(CenterOwner/CenterScreen)?
  • 如何設置窗口一直停留在顯示在中間?

我們先了解一下,有哪些觸發機制

  • Activated 窗口激活
    窗口變更為前臺窗口時(即顯示在最前面),會觸發
  • IsVisibleChanged 顯示變更
    當我們設置窗口隱藏Hide()時,IsVisibile=false.窗口再次ShowDialog時,IsVisibile=true;
  • 利用如上倆種機制,下面就可以搞事情了。

    首先定義幾個枚舉:

    1 /// <summary> 2 /// 窗口顯示變更觸發時機 3 /// </summary> 4 public enum WindowLocationInvokeOccasion 5 { 6 /// <summary> 7 /// 只要Activated就顯示在中間 8 /// </summary> 9 Activated = 0, 10 11 /// <summary> 12 /// 只在第一次Activated時,顯示在中間一次,之后的變化就不修改 13 /// </summary> 14 FirstActivated, 15 16 /// <summary> 17 /// 窗口每次顯示時,窗口居中 18 /// <para>可以解決單實例窗口彈出不居中問題</para> 19 /// </summary> 20 Visibile, 21 22 /// <summary> 23 /// 窗口每次顯示時,如父窗口與當前窗口不在同一屏幕時,窗口居中 24 /// <para>可以解決單實例窗口彈出不居中問題</para> 25 /// </summary> 26 VisibileInDifferentScreen, 27 28 /// <summary> 29 /// 不觸發 30 /// </summary> 31 Defatult 32 }

    如上枚舉包含了4種觸發機制。

    我們再定義個附加屬性,通過附加屬性去設置窗口的額外功能-居中顯示觸發機制

    1 /// <summary> 2 /// 窗口顯示居中觸發時機 3 /// <para>另:居中顯示設置,請使用<see cref="Window"/><see cref="WindowStartupLocation"/>屬性</para> 4 /// </summary> 5 public static readonly DependencyProperty InvokeOccasionProperty = DependencyProperty.RegisterAttached( 6 "InvokeOccasion", typeof(WindowLocationInvokeOccasion), typeof(WindowLocationOptions), 7 new PropertyMetadata(default(WindowLocationInvokeOccasion), InvokeOccasionProperty_ChangedCallback));

    在屬性更改觸發事件中,根據不同的觸發條件,設置不同的居中顯示。

    • Activated --只要Activated就顯示在中間
      每次觸發,直接顯示窗口即可
    • 首次Activated
      通過設置window.Activated -= ShowInCenter_Activated;禁用下次觸發進入
    • Visibile
    • VisibileInDifferentScreen
      窗口顯示時,如父窗口與當前窗口不在同一屏幕時,窗口居中.
      怎么判斷當前子窗口與父窗口是否在同一屏幕?
    1 var screen = Screen.FromHandle(new WindowInteropHelper(parentWindow).Handle); 2 3 Graphics currentGraphics = Graphics.FromHwnd(new WindowInteropHelper(parentWindow).Handle); 4 double dpiXRatio = currentGraphics.DpiX / 96; 5 double dpiYRatio = currentGraphics.DpiY / 96; 6 7 //當子窗口與父窗口所在屏幕相同時,不作處理 8 var isSubWindowInSameScreen = subWindow.Left > screen.Bounds.Left / dpiXRatio && 9 subWindow.Left < screen.Bounds.Left / dpiXRatio + screen.Bounds.Width / dpiXRatio && 10 subWindow.Top > screen.Bounds.Top / dpiYRatio && 11 subWindow.Top < screen.Bounds.Top / dpiYRatio + screen.Bounds.Height / dpiYRatio; 12 return isSubWindowInSameScreen;

    ?

    介紹完成觸發條件,下面說下窗口居中顯示。
    居中顯示,分為當前屏幕內居中/主窗口內居中,直接上代碼

    1.在主窗口中居中顯示-CenterOwner

    設置窗口的依靠位置Location(Left,Top)(左上角)

    • 子窗口最大化時 --WindowState=“Maximized”最大化窗口,固定的彈出到主屏幕,因此需額外處理,根據屏幕Location設置位置;
    • 父窗口最大化時 --父窗口最大化時,父窗口的location,因窗口設置margin,有可能不準確,故取屏幕位置
    • CenterOwner窗口居中顯示 --直接取父窗口的位置/大小和子窗口的大小,進行計算即可

    PS:窗口的位置Left/Top可能為負

    1 /// <summary> 2 /// 在主窗口中居中顯示 3 /// </summary> 4 /// <param name="subWindow"></param> 5 /// <param name="parentWindow"></param> 6 private static void SetWindowInCenterOwner(Window subWindow, Window parentWindow) 7 { 8 //最大化窗口,固定的彈出到主屏幕,因此需額外處理 9 if (subWindow.WindowState == WindowState.Maximized) 10 { 11 //子窗口最大化時,需要根據屏幕設置位置; 12 var screen = Screen.FromHandle(new WindowInteropHelper(parentWindow).Handle); 13 14 Graphics currentGraphics = Graphics.FromHwnd(new WindowInteropHelper(parentWindow).Handle); 15 double dpiXRatio = currentGraphics.DpiX / 96; 16 double dpiYRatio = currentGraphics.DpiY / 96; 17 18 subWindow.Left = screen.Bounds.Left / dpiXRatio; 19 subWindow.Top = screen.Bounds.Top / dpiYRatio; 20 } 21 if (parentWindow.WindowState == WindowState.Maximized) 22 { 23 //父窗口最大化時,父窗口的location,因窗口設置margin,有可能不準確,故取屏幕位置 24 var screen = Screen.FromHandle(new WindowInteropHelper(parentWindow).Handle); 25 26 Graphics currentGraphics = Graphics.FromHwnd(new WindowInteropHelper(parentWindow).Handle); 27 double dpiXRatio = currentGraphics.DpiX / 96; 28 double dpiYRatio = currentGraphics.DpiY / 96; 29 30 //窗口居中顯示 31 subWindow.Left = screen.Bounds.Left / dpiXRatio + 32 (screen.Bounds.Width / dpiXRatio - subWindow.ActualWidth) / 2; 33 subWindow.Top = screen.Bounds.Top / dpiYRatio + 34 (screen.Bounds.Height / dpiYRatio - subWindow.ActualHeight) / 2; 35 } 36 else 37 { 38 //窗口居中顯示 39 subWindow.Left = parentWindow.Left + (parentWindow.ActualWidth - subWindow.ActualWidth) / 2; 40 subWindow.Top = parentWindow.Top + (parentWindow.ActualHeight - subWindow.ActualHeight) / 2; 41 } 42 }

    2.當前屏幕內居中-CenterScreen

    窗口位置設置和上面的一樣,值得注意的是DPI。

    通過win的顯示設置,調整文本顯示比例,屏幕的位置轉換(X,Y),得考慮DPI的換算

    1 /// <summary> 2 /// 在父窗口所在屏幕居中顯示 3 /// </summary> 4 /// <param name="subWindow"></param> 5 /// <param name="parentWindow"></param> 6 private static void SetWindowInCenterScreen(Window subWindow, Window parentWindow) 7 { 8 SetWindowLocationInScreen(subWindow, parentWindow, subWindow.WindowState); 9 } 10 11 private const int DpiPercent = 96; 12 13 private static void SetWindowLocationInScreen(Window subWindow, Window parentWindow, WindowState windowState) 14 { 15 var intPtr = new WindowInteropHelper(parentWindow).Handle; 16 var screen = Screen.FromHandle(intPtr); 17 18 using (Graphics currentGraphics = Graphics.FromHwnd(intPtr)) 19 { 20 double dpiXRatio = currentGraphics.DpiX / DpiPercent; 21 double dpiYRatio = currentGraphics.DpiY / DpiPercent; 22 23 if (windowState == WindowState.Maximized) 24 { 25 //設置全屏Location 26 subWindow.Left = screen.Bounds.Left / dpiXRatio; 27 subWindow.Top = screen.Bounds.Top / dpiYRatio; 28 } 29 else 30 { 31 //設置居中Location 32 subWindow.Left = screen.Bounds.Left / dpiXRatio + 33 (screen.Bounds.Width / dpiXRatio - subWindow.ActualWidth) / 2; 34 subWindow.Top = screen.Bounds.Top / dpiYRatio + 35 (screen.Bounds.Height / dpiYRatio - subWindow.ActualHeight) / 2; 36 } 37 } 38 }

    ?

    關鍵字:單實例窗口,窗口居中,CenterOwner,CenterScreen,當前屏幕DPI

    總結

    以上是生活随笔為你收集整理的WPF 窗口居中 变更触发机制的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲另类图区 | www.夜夜夜| 亚洲av无码乱码国产精品fc2 | 亚洲成人免费网站 | 正在播放一区 | 日韩黄色免费看 | 欧洲精品视频在线观看 | 精品人妻一区二区三区四区五区 | 日本天堂网在线 | 国产精品不卡av | 老汉色老汉首页av亚洲 | 日本免费一区二区三区视频 | av一二区| 日韩激情在线 | 午夜影院18| 午夜第一页 | 欧美精品videosex极品 | av在线有码| 国精产品一区一区三区有限公司杨 | 美女被艹视频网站 | 亚洲精品电影在线观看 | 久久成人在线观看 | 国产一级视频在线播放 | 欧美日韩成人一区 | 成年人性生活视频 | 日韩伦理一区二区 | 日韩毛片 | 午夜精品福利电影 | 国产精品suv一区二区三区 | 中文字幕av在线播放 | 久久婷婷一区二区 | 国产亚洲精品久久久久久777 | 国产猛男猛女超爽免费视频 | 久久国产成人精品国产成人亚洲 | av福利在线免费观看 | 天天综合人人 | 一道本在线视频 | 91制服诱惑 | 中国色老太hd | 日韩视频在线免费播放 | 国产特黄级aaaaa片免 | 久久精品aⅴ无码中文字字幕重口 | 日本成人在线看 | www.啪| 精品国产不卡 | 亚洲深夜在线 | wwwxxx日本免费 | 国产传媒视频 | 亚洲日本香蕉视频 | 在线视频 一区二区 | 国产美女黄网站 | 日韩一级视频 | 欧美日韩一级在线观看 | 午夜黄视频 | 久久精品aaaaaa毛片 | 男女做那个的全过程 | 日韩一级片在线观看 | 国产无套粉嫩白浆内谢 | 日韩城人免费 | 青青草华人在线 | 久久青青| 午夜不卡av免费 | 97人妻精品一区二区三区免费 | 国偷自拍 | 成人中文字幕+乱码+中文字幕 | 懂色av成人一区二区三区 | a视频免费看 | 麻豆传媒网址 | 99re5| 免费看污黄网站在线观看 | 日韩亚洲欧美在线观看 | 天天插综合网 | 欧美日韩另类视频 | 亚洲一区二区三区中文字幕 | 隔壁邻居是巨爆乳寡妇 | 男女在线观看 | 男人av的天堂 | 麻豆91在线观看 | 亚洲男同视频 | 黑人操亚洲女 | a视频免费观看 | 亚洲第一毛片 | 亚洲影视在线 | 免费观看黄色 | 麻豆射区 | 国产极品一区二区 | 久久精品导航 | 精品久久影院 | 在线观看羞羞漫画 | 91黄在线看 | 国产免费黄色小视频 | 欧美日韩亚洲国产精品 | 日本一区二区三区四区视频 | 国产一级精品毛片 | 久久综合久久鬼色 | 国产午夜无码视频在线观看 | 久久九九久久九九 | 北条麻妃在线一区 | 99精品视频免费 |