簡體   English   中英

如何創建沒有邊框的 WPF Window 只能通過手柄調整大小?

[英]How to create a WPF Window without a border that can be resized via a grip only?

如果在 WPF Window上設置ResizeMode="CanResizeWithGrip"則在右下角顯示調整大小的夾點,如下所示:

如果您設置WindowStyle="None"以及標題欄消失,但灰色斜邊仍然存在,直到您設置ResizeMode="NoResize" 不幸的是,在設置了這種屬性組合后,調整大小的夾點也消失了。

我已經通過自定義Style覆蓋了WindowControlTemplate 我想自己指定 window 的邊框,並且我不需要用戶能夠從所有四個側面調整 window 的大小,但我確實需要調整大小的手柄。

有人可以詳細說明滿足所有這些標准的簡單方法嗎?

  1. 除了我在ControlTemplate中指定的邊框之外, Window沒有邊框。
  2. 右下角有一個有效的調整大小手柄。
  3. 沒有標題欄。

如果在Window上設置AllowsTransparency屬性(即使沒有設置任何透明度值),邊框也會消失,您只能通過夾點調整大小。

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="640" Height="480" 
    WindowStyle="None"
    AllowsTransparency="True"
    ResizeMode="CanResizeWithGrip">

    <!-- Content -->

</Window>

結果如下:

我試圖用WindowStyle="None"創建一個無邊框 window 但是當我測試它時,似乎頂部出現了一個白條,經過一些研究它似乎是一個“調整邊框大小”,這是一張圖片(我說黃色):

挑戰

經過互聯網的一些研究,以及許多困難的非 xaml 解決方案,我發現的所有解決方案都是 C# 和大量代碼行中的代碼,我在這里間接找到了解決方案: 最大自定義 Z05B8C74CBD96FBF2DE4C1A352702FFF4Z

<WindowChrome.WindowChrome>
    <WindowChrome 
        CaptionHeight="0"
        ResizeBorderThickness="5" />
</WindowChrome.WindowChrome>

注意:您需要使用 .NET 4.5 框架,或者如果您使用的是舊版本使用 WPFShell,只需參考 shell 並使用Shell:WindowChrome.WindowChrome

我使用了 Window 的WindowChrome屬性,如果你使用它,白色的“調整邊框”就會消失,但是你需要定義一些屬性才能正常工作。

CaptionHeight:這是標題區域(標題欄)的高度,允許像普通標題欄一樣進行 Aero 捕捉、雙擊行為。 將此設置為 0(零)以使按鈕工作。

ResizeBorderThickness:這是 window 邊緣的厚度,您可以在此處調整 window 的大小。 我設置為 5 是因為我喜歡這個數字,而且如果你設置為零,則很難調整 window 的大小。

使用此短代碼后,結果如下:

解決方案

現在,在沒有使用ResizeMode="NoResize"AllowsTransparency="True"的情況下,白色邊框消失了,它還在 window 中顯示了陰影。

稍后我將解釋如何使用簡單而簡短的代碼輕松地制作按鈕(我沒有使用圖像作為按鈕),我是新手,我認為我可以發布到 codeproject,因為在這里我沒有找到這個地方發布教程。

也許還有另一種解決方案(我知道對於像我這樣的菜鳥來說有困難和困難的解決方案)但這適用於我的個人項目。

這是完整的代碼

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:Concursos"
    mc:Ignorable="d"
    Title="Concuros" Height="350" Width="525"
    WindowStyle="None"
    WindowState="Normal" 
    ResizeMode="CanResize"
    >
<WindowChrome.WindowChrome>
    <WindowChrome 
        CaptionHeight="0"
        ResizeBorderThickness="5" />
</WindowChrome.WindowChrome>

    <Grid>

    <Rectangle Fill="#D53736" HorizontalAlignment="Stretch" Height="35" VerticalAlignment="Top" PreviewMouseDown="Rectangle_PreviewMouseDown" />
    <Button x:Name="Btnclose" Content="r" HorizontalAlignment="Right" VerticalAlignment="Top" Width="35" Height="35" Style="{StaticResource TempBTNclose}"/>
    <Button x:Name="Btnmax" Content="2" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,0,35,0" Width="35" Height="35" Style="{StaticResource TempBTNclose}"/>
    <Button x:Name="Btnmin" Content="0" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,0,70,0" Width="35" Height="35" Style="{StaticResource TempBTNclose}"/>

</Grid>

謝謝!

雖然公認的答案非常正確,但只想指出 AllowTransparency 有一些缺點。 它不允許子 window 控件出現,即 WebBrowser,它通常會強制軟件渲染,這可能會對性能產生負面影響。

不過有更好的解決方法。

當您想要創建一個沒有可調整大小的邊框的 window 並且能夠承載指向 URL 的 WebBrowser 控件或 Frame 控件時,您根本做不到,所述控件的內容將顯示為空。

不過,我找到了解決方法; in the Window, if you set the WindowStyle to None, ResizeMode to NoResize (bear with me, you will still be able to resize once done) then make sure you have UNCHECKED AllowsTransparency you will have a static sized window with no border and will show瀏覽器控件。

現在,您可能仍然希望能夠調整大小,對吧? 好吧,我們可以通過互操作調用來做到這一點:

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

    [DllImportAttribute("user32.dll")]
    public static extern bool ReleaseCapture();

    //Attach this to the MouseDown event of your drag control to move the window in place of the title bar
    private void WindowDrag(object sender, MouseButtonEventArgs e) // MouseDown
    {
        ReleaseCapture();
        SendMessage(new WindowInteropHelper(this).Handle,
            0xA1, (IntPtr)0x2, (IntPtr)0);
    }

    //Attach this to the PreviewMousLeftButtonDown event of the grip control in the lower right corner of the form to resize the window
    private void WindowResize(object sender, MouseButtonEventArgs e) //PreviewMousLeftButtonDown
    {
        HwndSource hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource;
        SendMessage(hwndSource.Handle, 0x112, (IntPtr)61448, IntPtr.Zero);
    }

瞧,A WPF window 沒有邊框,仍然可以移動和調整大小,而不會失去與 WebBrowser 等控件的兼容性

樣品在這里:

<Style TargetType="Window" x:Key="DialogWindow">
        <Setter Property="AllowsTransparency" Value="True"/>
        <Setter Property="WindowStyle" Value="None"/>
        <Setter Property="ResizeMode" Value="CanResizeWithGrip"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Window}">
                    <Border BorderBrush="Black" BorderThickness="3" CornerRadius="10" Height="{TemplateBinding Height}"
                            Width="{TemplateBinding Width}" Background="Gray">
                        <DockPanel>
                            <Grid DockPanel.Dock="Top">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition></ColumnDefinition>
                                    <ColumnDefinition Width="50"/>
                                </Grid.ColumnDefinitions>
                                <Label Height="35" Grid.ColumnSpan="2"
                                       x:Name="PART_WindowHeader"                                            
                                       HorizontalAlignment="Stretch" 
                                       VerticalAlignment="Stretch"/>
                                <Button Width="15" Height="15" Content="x" Grid.Column="1" x:Name="PART_CloseButton"/>
                            </Grid>
                            <Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
                                        Background="LightBlue" CornerRadius="0,0,10,10" 
                                        Grid.ColumnSpan="2"
                                        Grid.RowSpan="2">
                                <Grid>
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition/>
                                        <ColumnDefinition Width="20"/>
                                    </Grid.ColumnDefinitions>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="*"/>
                                        <RowDefinition Height="20"></RowDefinition>
                                    </Grid.RowDefinitions>
                                    <ResizeGrip Width="10" Height="10" Grid.Column="1" VerticalAlignment="Bottom" Grid.Row="1"/>
                                </Grid>
                            </Border>
                        </DockPanel>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

我很難得到@fernando-aguirre 使用WindowChrome工作的答案。 在我的情況下它不起作用,因為我在MainWindow中覆蓋OnSourceInitialized並且沒有調用基本 class 方法。

protected override void OnSourceInitialized(EventArgs e)
{
    ViewModel.Initialize(this);
    base.OnSourceInitialized(e); // <== Need to call this!
}

這讓我難過了很長時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM