Как создать окно WPF без границы, размер которого можно изменять только с помощью ручки?
-
03-07-2019 - |
Вопрос
Если вы установите ResizeMode="CanResizeWithGrip"
в WPF Window
затем в правом нижнем углу отображается ручка изменения размера, как показано ниже:
Если вы установите WindowStyle="None"
кроме того, строка заголовка исчезнет, но серый скошенный край останется до тех пор, пока вы не установите ResizeMode="NoResize"
.К сожалению, при такой комбинации установленных свойств ручка изменения размера также исчезает.
Я переопределил Window
's ControlTemplate
с помощью пользовательского Style
.Я хочу сам указать границу окна, и мне не нужно, чтобы пользователи могли изменять размер окна со всех четырех сторон, но мне нужна ручка изменения размера.
Может ли кто-нибудь подробно описать простой способ соответствовать всем этим критериям?
- Не делайте этого иметь границу на
Window
помимо того, который я указываю сам вControlTemplate
. - Делать установите рабочую ручку изменения размера в правом нижнем углу.
- Не делайте этого есть строка заголовка.
Решение
Если вы установите AllowsTransparency
собственность на Window
(даже без установки каких-либо значений прозрачности) граница исчезает, и вы можете изменять размер только с помощью ручки.
<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"
но когда я протестировал это, кажется, что вверху появляется белая полоса, после некоторого исследования она выглядит как "Граница изменения размера", вот изображение (я выделил желтым цветом):
После некоторых исследований в Интернете и множества сложных решений, отличных от xaml, все решения, которые я нашел, были написаны на C # и содержали множество строк кода, я косвенно нашел решение здесь: Максимальное пользовательское окно теряет эффект отбрасываемой тени
<WindowChrome.WindowChrome>
<WindowChrome
CaptionHeight="0"
ResizeBorderThickness="5" />
</WindowChrome.WindowChrome>
Примечание :Вам нужно использовать .NET 4.5 Framework, или, если вы используете более старую версию, используйте WPFShell, просто обратитесь к оболочке и используйте Shell:WindowChrome.WindowChrome
вместо этого.
Я использовал WindowChrome
свойство Window, если вы используете это, то белая "граница изменения размера" исчезает, но вам нужно определить некоторые свойства для корректной работы.
Высота надписи: Это высота области заголовка (headerbar), которая позволяет выполнять аэрофотосъемку двойным щелчком мыши, как это делает обычная строка заголовка.Установите это значение в 0 (ноль), чтобы заставить кнопки работать.
Измените размер толщины: Это толщина по краю окна, где вы можете изменить размер окна.Я ставлю 5, потому что мне нравится это число, и потому что, если вы поставите ноль, вам будет трудно изменить размер окна.
После использования этого короткого кода результатом будет следующее:
И теперь белая кайма исчезла без использования ResizeMode="NoResize"
и AllowsTransparency="True"
, также он показывает тень в окне.
Позже я объясню, как заставить кнопки работать (я не использовал изображения для кнопок) легко с помощью простого и короткого кода, я новичок и думаю, что могу опубликовать в 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>
Спасибо!
Хотя общепринятый ответ очень верен, просто хочу отметить, что разрешение прозрачности имеет некоторые недостатки.Это не позволяет отображать дочерние элементы управления окнами, то есть WebBrowser, и обычно приводит к программному рендерингу, который может негативно сказаться на производительности.
Однако есть способ получше обойти проблему.
Если вы хотите создать окно без границ с возможностью изменения размера и возможностью размещения элемента управления WebBrowser или элемента управления Frame, указывающего на URL, который вы просто не смогли бы использовать, содержимое указанного элемента управления будет отображаться пустым.
Однако я нашел обходной путь;в окне, если вы установите для WindowStyle значение None, измените размер на NoResize (потерпите, вы все равно сможете изменить размер после завершения), затем убедитесь, что у вас СНЯТ ФЛАЖОК AllowsTransparency, у вас будет окно статического размера без границ, и в нем будет отображаться элемент управления браузера.
Теперь вы, вероятно, все еще хотите иметь возможность изменять размер, не так ли?Что ж, мы можем сделать это с помощью вызова interop:
[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);
}
И вуаля, окно WPF без границ, которое по-прежнему можно перемещать и изменять без потери совместимости с элементами управления, такими как 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>