精华内容
下载资源
问答
  • WPF 窗口居中 & 变更触发机制 原文:WPF 窗口居中 & 变更触发机制窗口居中 & 变更触发机制 解决: 1。单实例窗口,窗口每次隐藏后再显示时,位置居中显示 2。多屏幕下单实例窗口,当父...
    原文:WPF 窗口居中 & 变更触发机制

    窗口居中 & 变更触发机制

    解决:

    1。单实例窗口,窗口每次隐藏后再显示时,位置居中显示

    2。多屏幕下单实例窗口,当父窗口移动到其它屏幕时,单实例窗口再次弹出时,位置才更新到父窗口屏幕。

    3。子窗口每次唤醒时,都居中显示。

    窗口首次显示的位置 - WindowStartupLocation

    windows的启动时位置显示,WindowStartupLocation

    • CenterOwner --显示在父窗口的中间(设置Owner)
    • CenterScreen --显示在当前屏幕中间
    • Manual --默认位置

    当第一次window.ShowDialog时,window显示如上设置。

    变更触发机制

    上面只涉及到了首次显示位置,之后,窗口的位置会继续保留

    • 如何设置窗口隐藏之后再次弹出时,显示在中间(CenterOwner/CenterScreen)?
    • 如何设置窗口一直停留在显示在中间?

    我们先了解一下,有哪些触发机制

    1. Activated 窗口激活
      窗口变更为前台窗口时(即显示在最前面),会触发
    2. 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

    posted on 2018-09-25 08:49 NET未来之路 阅读(...) 评论(...) 编辑 收藏

    转载于:https://www.cnblogs.com/lonelyxmas/p/9697784.html

    展开全文
  • wpf 窗口标题居中

    2013-04-08 17:10:06
    诸位老师好。... 在wpf中窗体的title居中显示。目前是居左显示的。 如图效果。 [img=http://img.my.csdn.net/uploads/201304/08/1365412122_4977.png][/img] 如何能让其居中显示呢。 多谢了。
  • WPF随笔之窗口居中

    千次阅读 2018-02-02 14:45:20
    有时候我们设置Window的SizeToContent属性,希望窗口能够根据内容自动调整窗口大小,这时候问题就来了,窗口大小是改变了 但是窗口的位置有时间却很尴尬,我们希望窗口的位置也随之居中,其实可以通过SizeChanged...

    有时候我们设置Window的SizeToContent属性,希望窗口能够根据内容自动调整窗口大小,这时候问题就来了,窗口大小是改变了 但是窗口的位置有时间却很尴尬,我们希望窗口的位置也随之居中,其实可以通过SizeChanged事件进行改变:

    private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
    SizeChangedEventArgs有个属性叫NewSize,它是用来获取新的窗口大小,所以我们通过获取它的Width和Height就可以让窗口重新居中:
    Rect workArea = SystemParameters.WorkArea;
    Left = (workArea.Width - e.NewSize.Width) / 2 + workArea.Left;
    Top = (workArea.Height - e.NewSize.Height) / 2 + workArea.Top;
    SystemParameters.WorkArea表示的是显示器上的工作区域,完整的代码:
    private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
    {
         Rect workArea = SystemParameters.WorkArea;
         Left = (workArea.Width - e.NewSize.Width) / 2 + workArea.Left;
         Top = (workArea.Height - e.NewSize.Height) / 2 + workArea.Top;
    }

    展开全文
  • WPF窗口弹出居中显示

    2019-11-12 16:29:02
    private void Button_Click(object sender, RoutedEventArgs e) { //addCar(); Window window = new addCarForm(); window.WindowStartupLocation = WindowStartupL...
      private void Button_Click(object sender, RoutedEventArgs e)
            {
                //addCar();
                Window window = new addCarForm();
                window.WindowStartupLocation = WindowStartupLocation.CenterOwner;
                window.ShowDialog();
            }

     

    展开全文
  • public Window() { InitializeComponent(); WindowStartupLocation = WindowStartupLocation.CenterScreen; this.Topmost = true; } 转载于:https://w...

    public Window()

            {
                InitializeComponent();
                WindowStartupLocation = WindowStartupLocation.CenterScreen;
                this.Topmost = true;
            }

    转载于:https://www.cnblogs.com/kid526940065/p/8515474.html

    展开全文
  • 使用MVVM DataTriggers在WPF XAML视图之间切换/Window窗口自适应内容大小并居中 原文 使用MVVM DataTriggers在WPF XAML视图之间切换 相关文章: ...
  • 在xxx.xaml.cs文件构造函数处加上 WindowStartupLocation=WindowStartupLocation.CenterScreen; 如下所示: publicLogin() { InitializeComponent()...
  • WPF实现动画——旋转

    2020-05-17 17:57:48
    WPF实现动画——旋转 1、布局 布局为Canvas画布 2、对象 but.Background = Brushes.LightSteelBlue;...//设置位置在窗口居中 Canvas.SetLeft(but, this.Width / 2 - but.Width / 2); Canvas.SetTop(but, thi
  • wpf学习笔记

    2015-06-28 10:56:24
    1.菜单:普通菜单、上下文菜单(ContextMenu) Width="517"> 2.DockPanel:让元素靠左右上下; 3.Toolbar:放入其中的控件都有新的默认外观;...4.多窗口: ...窗口名字:window Title="";...居中
  • WPF布局实例

    2012-12-10 14:18:00
    1.Best ComboBox Tutorial,来自MSDN2.Textbox文本垂直居中对齐:TextBox.VerticalContentAlignment="Center"3.控件跟随窗口变化:VerticalAlignment="Stretch" HorizontalAlignment="Stretch"4.规划窗口: <Grid...
  • 1) 默认充满整个窗口。 2) 最后一个出现的部分,默认充满剩余空间。 3) 非最后一个出现的部分,根据其中内容,进行分配空间s 2 StackPanel 实现居左,居右,居中 利用Margin实现 <StackPanel DockPanel....
  • 实验内容:在主窗口上放置一ListBox和两个Button,Button1和Button2;新建Window窗体Form2,在Form2上放置一button;要求主窗体居中显示。点击主窗体上的button1,,弹出窗体Form2,实现点击Form2窗体上的按钮时,在...
  • 问题31 如何使窗口最大化、最小化、置顶和居中,如何在窗口中更换图标 312 问题32 怎样利用Uitable对象在列名、行名或单元格中输入上下标和希腊字母 313 问题33 如何更改菜单项的字体大小,如何设置菜单项的字体...

空空如也

空空如也

1
收藏数 20
精华内容 8
关键字:

wpf窗口居中