4

我正在创建一个带有自定义镶边的 WPF 窗口,因此我设置ResizeMode="NoResize"WindowStyle="None"实现了我自己的镶边。但是,在最大化无边框窗口时存在一个问题:它占据了整个屏幕。

我发现了以下技巧来解决部分问题: http ://chiafong6799.wordpress.com/2009/02/05/maximizing-a-borderlessno-caption-window/

这成功地限制了窗口大小以防止覆盖任务栏。但是,如果用户将他的任务栏放在左侧或顶部,这将不起作用,因为窗口位于位置 0,0。

有什么方法可以更准确地检索可用区域,或者查询用户任务栏的位置,以便我可以相应地定位最大化窗口?

4

2 回答 2

5

我快速玩了一下,似乎在设置无边框表单时忽略了设置Windows LeftandTop属性。WindowState.Maximized

一种解决方法是忽略WindowState函数并创建自己的Maximize/Restore函数

粗略的例子。

public partial class MainWindow : Window
{
    private Rect _restoreLocation;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void MaximizeWindow()
    {
        _restoreLocation = new Rect { Width = Width, Height = Height, X = Left, Y = Top };
        System.Windows.Forms.Screen currentScreen;
        currentScreen = System.Windows.Forms.Screen.FromPoint(System.Windows.Forms.Cursor.Position);
        Height = currentScreen.WorkingArea.Height;
        Width = currentScreen.WorkingArea.Width;
        Left = currentScreen.WorkingArea.X;
        Top = currentScreen.WorkingArea.Y;
    }

    private void Restore()
    {
        Height = _restoreLocation.Height;
        Width = _restoreLocation.Width;
        Left = _restoreLocation.X;
        Top = _restoreLocation.Y;
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        MaximizeWindow();
    }

    private void Button_Click_2(object sender, RoutedEventArgs e)
    {
        Restore();
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            DragMove();
        }
        base.OnMouseMove(e);
    }
}

xml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="74.608" Width="171.708" ResizeMode="NoResize" WindowStyle="None">
    <Grid>
        <Button Content="Max" HorizontalAlignment="Left" Margin="0,29,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
        <Button Content="Restore" HorizontalAlignment="Left" Margin="80,29,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_2"/>
    </Grid>
</Window>

显然你会想要清理这个代码,但它似乎在任何地方Taskbar都可以工作,但是你可能需要添加一些逻辑来获得正确的LeftTop如果用户字体 DPI 大于 100%

于 2013-02-10T22:45:45.003 回答
2

另一种方法是处理WM_GETMINMAXINFOWin32 消息。这里的代码显示了如何做到这一点。

请注意,我会做一些不同的事情,例如IntPtr.Zero在 WindowProc 中返回而不是 (System.IntPtr)0 并制作MONITOR_DEFAULTTONEAREST一个常量。但这只是编码风格的改变,并不影响最终结果。

还要确保注意在事件WindowProc期间挂钩的更新SourceInitialized而不是OnApplyTemplate. 那是最好的地方。如果您正在实现从 Window 派生的类,那么另一个选项是覆盖OnSourceInitialized以挂钩WindowProc而不是附加到事件。这就是我通常所做的。

于 2013-07-04T00:14:44.877 回答