我正在使用WPF Shell集成库来创建我的wpf应用程序的自定义chrome.一切都很好,但是当最大化应用程序时,屏幕外有6或7个像素.
这是我正在使用的代码:
<Style TargetType="{x:Type local:MainWindow}">
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome
ResizeBorderThickness="6"
CaptionHeight="10"
CornerRadius="0"
GlassFrameThickness="1"/>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MainWindow}">
<Grid>
<Border BorderThickness="1" BorderBrush="#389FD1" Background="#389FD1">
<ContentPresenter Margin="0,22,0,0" Content="{TemplateBinding Content}"/>
</Border>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" >
<TextBlock Text="{Binding NombreUsuario}" Foreground="White" Margin="5,5,20,5" Opacity=".8" />
<Button Style="{StaticResource ImageButton}" Height="20" Width="20" Margin="0" Click="WindowMinimize" shell:WindowChrome.IsHitTestVisibleInChrome="True">
<Image Height="10" Width="10" Source="/Resources/Images/minimize.png" />
</Button>
<Button Style="{StaticResource ImageButton}" Height="20" Width="20" Margin="0" Click="WindowMaximizeRestore" shell:WindowChrome.IsHitTestVisibleInChrome="True" >
<Image Height="10" Width="10" Source="/Resources/Images/maximize.png" />
</Button>
<Button Style="{StaticResource ImageButton}" Height="20" Width="20" Margin="0" Click="WindowClose" shell:WindowChrome.IsHitTestVisibleInChrome="True">
<Image Height="10" Width="10" Source="/Resources/Images/close.png" />
</Button>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)
Joe*_*tro 46
Windows会在窗口边缘最大化时裁剪窗口的边缘,以遮盖通常调整大小的边缘.您可以通过在窗口和内容之间放置代理边框来解决此问题,然后在最大化时增加厚度.
我修改了lib附带的示例来执行此操作,可以对您的示例进行相同的基本更改:
<ControlTemplate TargetType="{x:Type local:SelectableChromeWindow}">
<Border BorderBrush="Green">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Setter Property="BorderThickness" Value="0"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=ThisWindow, Path=WindowState}" Value="Maximized">
<Setter Property="BorderThickness" Value="{Binding Source={x:Static shell:SystemParameters2.Current}, Path=WindowResizeBorderThickness}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid [...]/>
</Border>
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)
我希望有所帮助.
对于.net 4.5及更高版本, SystemParameters略有不同,例如:
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MainWindow}}, Path=WindowState}" Value="Maximized">
<Setter Property="BorderThickness" Value="{Binding Source={x:Static SystemParameters.WindowResizeBorderThickness}}"/>
</DataTrigger>
Run Code Online (Sandbox Code Playgroud)
这对我有用:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="clr-namespace:Microsoft.Windows.Shell;assembly=Microsoft.Windows.Shell"
xmlns:Views="clr-namespace:BorderLessWpf.Views">
<Style TargetType="{x:Type Views:ShellView}" >
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome
ResizeBorderThickness="6"
CaptionHeight="10"
CornerRadius="0"
GlassFrameThickness="1"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="WindowState" Value="Maximized">
<Setter Property="BorderThickness" Value="6" />
</Trigger>
</Style.Triggers>
</Style>
Run Code Online (Sandbox Code Playgroud)
Raymond Chen has explained this in his note Why are the dimensions of a maximized window larger than the monitor?:
\n\n\n\n\nThe extra eight pixels that hang off the screen are the window\n borders. When you maximize a window, the window manager arranges\n things so that the client area of the window fills the width of your\n work area, and it plus the caption bar fills the height of the work\n area. After all, you want to see as much of your document as possible;\n there\xe2\x80\x99s no need to show you the window borders that aren\xe2\x80\x99t doing you\n any good. (It leaves the caption bar on the screen for obvious\n reasons.)
\n
@Joe Castro has proposed the right approach. You basically have to add a border (or specify a margin) around your window each time it maximizes. And SystemParameters.WindowResizeBorderThickness is also the right property, but ... it has a bug.
For me, it gives 4px border instead of correct 8px for 100% display scale (can be changed in Display Settings) and approximately 3px instead of correct 7px for 175%.
内部SystemParameters.WindowResizeBorderThickness使用GetSystemMetrics调用来获取边框的设备像素。它查询CXFRAME (32) and CYFRAME(33) indexes, and then converts it into logical pixels.
现在检查这个旧的错误报告:
\n\n\n\n\n采取以下代码行:
\n\nRun Code Online (Sandbox Code Playgroud)\n\nint cx = ::GetSystemMetrics(SM_CXSIZEFRAME);\n int cy = ::GetSystemMetrics(SM_CYSIZEFRAME);\n int cp = ::GetSystemMetrics(SM_CYCAPTION);\n当使用 Visual Studio 2010 编译时,在我的 Windows7 计算机上,\n 会生成:cx == 9、cy == 9 和 cp == 27。
\n\n如果我在同一台机器上使用 Vision Studio 2012 RC 编译完全相同的代码,则会产生:cx == 5、cy == 5 和 cp == 27。
\n
答案是:
\n\n\n\n\nMicrosoft 发布于 2012 年 7 月 12 日上午 11:03 \n 感谢您提交错误。您报告的问题似乎是 Windows 问题,\n我们已将该错误转发给他们。
\n
但是这个问题有一些好消息:GetSystemMetrics() returns different results for .NET 4.5 & .NET 4.0
\n\n对于 .NET 4.5 及更高版本,您只需SM_CXPADDEDBORDER (92)为两者添加值CXFRAME (32)即可CYFRAME(33)获取正确的值。
使用@Joe Castro 方法,但具有固定属性:
\n\npublic static class SystemParametersFix\n{\n public static Thickness WindowResizeBorderThickness\n {\n get\n {\n float dpix = GetDpi(GetDeviceCapsIndex.LOGPIXELSX);\n float dpiy = GetDpi(GetDeviceCapsIndex.LOGPIXELSY);\n\n int dx = GetSystemMetrics(GetSystemMetricsIndex.CXFRAME);\n int dy = GetSystemMetrics(GetSystemMetricsIndex.CYFRAME);\n\n // this adjustment is needed only since .NET 4.5 \n int d = GetSystemMetrics(GetSystemMetricsIndex.SM_CXPADDEDBORDER);\n dx += d;\n dy += d;\n\n var leftBorder = dx / dpix;\n var topBorder = dy / dpiy;\n\n return new Thickness(leftBorder, topBorder, leftBorder, topBorder);\n }\n }\n\n [DllImport("user32.dll")]\n private static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);\n\n [DllImport("user32.dll")]\n private static extern IntPtr GetDC(IntPtr hwnd);\n\n [DllImport("gdi32.dll")]\n private static extern int GetDeviceCaps(IntPtr hdc, int nIndex);\n\n private static float GetDpi(GetDeviceCapsIndex index)\n {\n IntPtr desktopWnd = IntPtr.Zero;\n IntPtr dc = GetDC(desktopWnd);\n float dpi;\n try\n {\n dpi = GetDeviceCaps(dc, (int)index);\n }\n finally\n {\n ReleaseDC(desktopWnd, dc);\n }\n return dpi / 96f;\n }\n\n private enum GetDeviceCapsIndex\n {\n LOGPIXELSX = 88,\n LOGPIXELSY = 90\n }\n\n [DllImport("user32.dll")]\n private static extern int GetSystemMetrics(GetSystemMetricsIndex nIndex);\n\n private enum GetSystemMetricsIndex\n {\n CXFRAME = 32,\n CYFRAME = 33,\n SM_CXPADDEDBORDER = 92\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
12115 次 |
| 最近记录: |