Jeśli ustawisz ResizeMode="CanResizeWithGrip"
na WPF, Window
uchwyt zmiany rozmiaru jest wyświetlany w prawym dolnym rogu, jak poniżej:
Jeśli również ustawisz, WindowStyle="None"
pasek tytułu zniknie, ale szara ścięta krawędź pozostanie do momentu ustawienia ResizeMode="NoResize"
. Niestety, przy tej kombinacji właściwości, uchwyt zmiany rozmiaru również znika.
Mam zastąpione przez Window
„s ControlTemplate
poprzez zwyczaju Style
. Chcę samodzielnie określić obramowanie okna i nie potrzebuję, aby użytkownicy mogli zmieniać rozmiar okna ze wszystkich czterech stron, ale potrzebuję uchwytu zmiany rozmiaru.
Czy ktoś może wyszczególnić prosty sposób spełnienia wszystkich tych kryteriów?
- Nie miej obramowania
Window
poza tą, którą określam w aControlTemplate
. - Miej działający uchwyt zmiany rozmiaru w prawym dolnym rogu.
- Nie mają paska tytułu.
.net
wpf
window
controltemplate
resizegrip
Drew Noakes
źródło
źródło
Odpowiedzi:
Jeśli ustawisz
AllowsTransparency
właściwość naWindow
(nawet bez ustawiania wartości przezroczystości), obramowanie znika i możesz zmienić rozmiar tylko za pomocą uchwytu.<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>
Wynik wygląda następująco:
źródło
Próbowałem stworzyć okno bez obramowania,
WindowStyle="None"
ale kiedy je testowałem, wydaje się, że pojawia się biały pasek na górze, po kilku badaniach wydaje się, że jest to "Ramka zmiany rozmiaru", oto obraz (zauważyłem na żółto):Po kilku poszukiwaniach w Internecie i wielu trudnych rozwiązaniach innych niż XAML, wszystkie rozwiązania, które znalazłem, zawierały kod w C # i wiele linii kodu, znalazłem pośrednio rozwiązanie tutaj: Maksymalne niestandardowe okno traci efekt cienia
<WindowChrome.WindowChrome> <WindowChrome CaptionHeight="0" ResizeBorderThickness="5" /> </WindowChrome.WindowChrome>
Uwaga : Musisz użyć platformy .NET 4.5 lub, jeśli używasz starszej wersji, użyj WPFShell, po prostu odwołaj się do powłoki i użyj
Shell:WindowChrome.WindowChrome
zamiast niej.Użyłem
WindowChrome
właściwości Window, jeśli używasz tego, białe "obramowanie zmiany rozmiaru" znika, ale musisz zdefiniować niektóre właściwości, aby działały poprawnie.CaptionHeight: Jest to wysokość obszaru podpisu (paska nagłówka), który umożliwia przyciąganie Aero, zachowanie dwukrotnego kliknięcia, jak w przypadku zwykłego paska tytułu. Ustaw to na 0 (zero), aby przyciski działały.
ResizeBorderThickness: Jest to grubość na krawędzi okna, w której możesz zmienić rozmiar okna. Ustawiłem na 5, ponieważ podoba mi się ta liczba i ponieważ jeśli ustawisz zero, trudno jest zmienić rozmiar okna.
Po użyciu tego krótkiego kodu wynik jest taki:
A teraz biała ramka zniknęła bez użycia,
ResizeMode="NoResize"
aAllowsTransparency="True"
także pokazuje cień w oknie.Później wyjaśnię jak sprawić, aby przyciski działały (nie użyłem obrazków do przycisków) w prosty i krótki kod, jestem nowy i myślę, że mogę pisać do codeproject, bo tutaj nie znalazłem miejsca aby opublikować samouczek.
Może jest inne rozwiązanie (wiem, że są trudne i trudne rozwiązania dla noobów takich jak ja), ale to działa w przypadku moich osobistych projektów.
Oto pełny kod
<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>
Dziękuję Ci!
źródło
Rectangle_PreviewMouseDown
poprawnie zinterpretuję użycie zdarzenia.Chociaż przyjęta odpowiedź jest bardzo prawdziwa, chcę tylko zwrócić uwagę, że AllowTransparency ma pewne wady. Nie pozwala na wyświetlanie elementów sterujących okna potomnego, np. WebBrowser, i zazwyczaj wymusza renderowanie oprogramowania, które może mieć negatywny wpływ na wydajność.
Jest jednak lepsza obejście.
Jeśli chcesz utworzyć okno bez obramowania, którego rozmiar można zmienić i jest w stanie hostować formant WebBrowser lub formant Frame wskazujący na adres URL, którego po prostu nie mogłeś, zawartość wspomnianej kontrolki byłaby pusta.
Znalazłem jednak obejście; w oknie, jeśli ustawisz WindowStyle na None, ResizeMode na NoResize (proszę ze mną, nadal będziesz mógł zmienić rozmiar po zakończeniu), a następnie upewnij się, że masz UNCHECKED AllowsTransparency, będziesz mieć statyczne okno bez obramowania i pokaże kontrolka przeglądarki.
Teraz prawdopodobnie nadal chcesz mieć możliwość zmiany rozmiaru, prawda? Cóż, możemy to zrobić za pomocą połączenia międzyoperacyjnego:
[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); }
I voila, okno WPF bez obramowania, nadal ruchome i skalowalne bez utraty zgodności z kontrolkami takimi jak WebBrowser
źródło
private enum ResizeDirection { Left = 61441, Right = 61442, Top = 61443, TopLeft = 61444, TopRight = 61445, Bottom = 61446, BottomLeft = 61447, BottomRight = 61448, }
Próbka tutaj:
<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>
źródło
Miałem trudności z uzyskaniem odpowiedzi przy użyciu @ fernando-aguirre
WindowChrome
do pracy. To nie działa w moim przypadku bo nadrzędneOnSourceInitialized
wMainWindow
a nie wywołanie metody klasy bazowej.protected override void OnSourceInitialized(EventArgs e) { ViewModel.Initialize(this); base.OnSourceInitialized(e); // <== Need to call this! }
Dręczyło mnie to bardzo długo.
źródło