Auto和SizeToContent =“Height”上的WPF滚动条位于Windows7工具栏下

时间:2014-09-11 14:52:14

标签: wpf windows-7 scrollbar

我有一个特殊的问题,其中WPF滚动条设置为AutoWindow设置为SizeToContent="Height"自身尺寸在Windows 7工具栏下。

enter image description here

XAML真是微不足道。

<Window x:Class="....ProbateControllerView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       Title="Probate" Width="1100" ResizeMode="CanMinimize" Background="White" SizeToContent="Height">
    <Grid>
        <ScrollViewer VerticalScrollBarVisibility="Auto" >
            <StackPanel>
                <ContentControl HorizontalAlignment="Center" DockPanel.Dock="Top" x:Name="ActiveItem"/>
            </StackPanel>
        </ScrollViewer>
    </Grid>
</Window>

我可以添加Height并将SizeToContent="Manual"设置为常量Window但是当分辨率较低时,我会遇到同样的问题。
我相信现在有人遇到了这个问题,我必须在这里遗漏一些东西。

4 个答案:

答案 0 :(得分:3)

您可以在窗口的构造函数中将Window的MaxHeight设置为SystemParameters.MaximizedPrimaryScreenHeight

public MainWindow()
{
    InitializeComponent();
    this.MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
}
对于我来说,对于我来说,窗口仍然隐藏在任务栏后面,但调整为20时它看起来很好。

this.MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight-20;

我已经在各种操作系统和屏幕分辨率上尝试了这一点,并且20的调整似乎在Windows 7/8上运行良好。在XP等上,调整是不必要的,因此最终窗口略小于屏幕高度。我想如果这是一个问题,你可以检测操作系统版本并在必要时应用调整。

如果您不需要应用调整,可以在xaml中定义:

MaxHeight="{DynamicResource {x:Static SystemParameters.MaximizedPrimaryScreenHeightKey}}"

答案 1 :(得分:2)

不幸的是,没有简单的方法可以使用XAML标记来解决这个问题。

其他答案考虑SystemParameters.MaximizedPrimaryScreenHeightSystemParameters.WorkArea,因此仅考虑主要屏幕。但是,如果此窗口将显示在具有不同屏幕分辨率的辅助屏幕上,会发生什么?

我建议你使用一个小的P / Invoke代码片段来找出窗口将显示在的屏幕。

我们需要两个WinAPI函数:

[DllImport("user32.dll")]
static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);

[DllImport("user32.dll")]
static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);

他们使用.NET中缺少的WinAPI本机数据结构和常量,因此我们也必须定义它们:

[StructLayout(LayoutKind.Sequential)]
private struct MONITORINFO
{
    public int cbSize;
    public RECT rcMonitor, rcWork;
    public uint dwFlags;
}

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int Left, Top, Right, Bottom;
}

const int MONITOR_DEFAULTTONEAREST = 2;

在Windows的构造函数中,订阅SourceInitialized事件。当创建并初始化基础Win32窗口时,将引发此事件。

public Window1()
{
    this.InitializeComponent();
    this.SourceInitialized += Window1_SourceInitialized;         
}

在该事件处理程序中,只需根据屏幕工作区域设置窗口的MaxHeight属性(即 - 排除任务栏)。

void Window1_SourceInitialized(object sender, EventArgs e)
{
    // First, get the window handle
    IntPtr hwnd = (new WindowInteropHelper(this)).Handle;

    // Obtain the screen the windows will be displayed on
    IntPtr hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);

    // If we've got the monitor...
    if (hMonitor != IntPtr.Zero)
    {
        MONITORINFO mi = new MONITORINFO();
        mi.cbSize = Marshal.SizeOf(mi);

        // ...and the monitor information, then we set the size constraint
        if (GetMonitorInfo(hMonitor, ref mi))
        {
            this.MaxHeight = mi.rcWork.Bottom - mi.rcWork.Top;
        }
    }
}

此外,如果您愿意,您可以订阅窗口的LocationChanged事件,您可以根据此窗口当前显示的屏幕分辨率更改窗口的最大高度上。但是,这可能有点困难:如果窗口将同时显示在多个屏幕上(特别是当它们都具有不同的屏幕分辨率时)会发生什么?

答案 2 :(得分:1)

这是怎么回事?如果它溢出屏幕,它将关闭SizeToContent并最大化窗口:

    private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
    {
        if (ActualHeight > SystemParameters.MaximizedPrimaryScreenHeight)
        {
            SizeToContent = SizeToContent.Manual;
            WindowState = WindowState.Maximized;
        }
        else
        {
            WindowState = WindowState.Normal;
            SizeToContent = System.Windows.SizeToContent.Height;
        }
    }
  • 如果这是不可接受的,请使用Gary Wright解决方案。我不会让您重新使用这些Win32 API,因为无法保证它可以在不同的系统上运行,例如Windows 10
  • 如果您有多个不同高度的显示器,您可以显示&#34;透明最大化窗口测量它(ActualHeight属性)以获取工作空间大小

答案 3 :(得分:-2)

你必须删除&#34; SizeToContent&#34;属性,因为它将调整窗口大小以适应其内容。

为什么必须指定它?