Rahmenlose Fenster mit WPF
Achtung, das folgende Beispiel bringt wahrscheinlich keinen Nutzen für den täglichen Umgang mit WPF!
EGAL! Manchmal muss man eben auch spielen
. Rahmenlose Fenster sind einfach cool. Wenn dann auch noch ein guter Designer mit im Spiel ist, sieht das Ganze auch besser aus als bei meinem Versuch.
Ok, Design beiseite. Was ist zu tun um eine Anwendung mit einem rahmenlosen Fenster zu erstellen?
Der erste Schritt besteht darin, an dem Fenster der Applikation drei Eigenschaften entsprechend zu setzen:
- AllowsTransparency auf true
- WindowStyle auf None – in Verbindung mit AllowsTransparency=”True” wird erreicht, dass der Fensterrahmen und die Titelzeile verschwinden
- Background auf Transparent
<Window x:Class="NonRectShapedWindowWPF.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="215" Height="215" AllowsTransparency="True" WindowStyle="None" Background="Transparent"> ...In meinem Beispiel habe ich mich dazu entschieden das UI aus zwei Kreisen zusammenzusetzen. Der grosse Kreis dient als “Hauptrahmen” der Anwendung und der kleine Kreis enthält einen “Close” Button.
...
<Grid Height="200" Width="200">
<Ellipse Fill="Red" Stroke="DarkRed"
MouseLeftButtonDown="OnCircleMouseLeftButtonDown">
<Ellipse.BitmapEffect>
<OuterGlowBitmapEffect GlowSize="8" GlowColor="OrangeRed" />
</Ellipse.BitmapEffect>
</Ellipse>
<Canvas...>
<Button Margin="150 -150 0 0"
Template="{StaticResource closeButton}"
FontFamily="Webdings"
FontWeight="Bold"
FontSize="10"
Content="r"
Click="OnCloseButtonClick"
ToolTip="Close">
</Button>
</Grid>
...
Der eigentliche Inhalt der Anwendung versteckt sich in dem zusammengeklappten <Canvas> Element. Die Details dazu gibt es weiter unten.
Wie in dem XAML Code zu sehen ist, wird der “Close” Button über die Margin Eigenschaft an der gewünschten Stelle positioniert. Um dem Button ein rundes Aussehen zu verpassen, habe ich ein ControlTemplate erstellt.
...
<ControlTemplate x:Key="closeButton" TargetType="{x:Type Button}">
<Grid>
<Ellipse Fill="Red" Stroke="DarkRed"
Width="25" Height="25"/>
<Label Content="{TemplateBinding Content}"
Foreground="Black"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
...
Um dem Anwender ein Verschieben des Fensters zu ermöglichen, fügt man einen Eventhandler für das MouseLeftButtonDown Event hinzu. Und zwar an dem Element, mit dem das Fenster verschoben werden soll. Das könnte z.B. eine eigene Titelleiste sein, oder wie bei mir irgendein anderes, sichtbares Element. Der Code in dem Eventhandler ist sehr einfach:
private void OnCircleMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DragMove();
}
Ein weiterer Eventhandler wird für das Click Event unseres “Close” Buttons benötigt um das Fenster zu schliessen:
private void OnCloseButtonClick(object sender, RoutedEventArgs e)
{
Close();
}
Damit sind die wichtigsten Schritte gemacht, um ein rahmenloses Fenster mit WPF zu erstellen. Es kann vom Anwender verschoben und geschlossen werden. Um ein bisschen Action in das Beispiel zu bringen, gibt es noch eine kleine Animation, die Text durch das Fenster scrollen lässt. Der Code dazu sieht so aus:
...
<Canvas Height="100" Width="120" ClipToBounds="True">
<TextBlock x:Name="_text"
Height="100" Width="120"
VerticalAlignment="Center" HorizontalAlignment="Center"
TextWrapping="Wrap"
FontFamily="Tahoma" FontSize="12">
<TextBlock.Text>
Diese Anwendung ist völlig sinnlos. Zu nichts zu gebrauchen. Und doch hat es viel Spass
gemacht sie zu erstellen.
</TextBlock.Text>
<TextBlock.Triggers>
<EventTrigger RoutedEvent="TextBlock.Loaded" >
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="_text"
Storyboard.TargetProperty="(Canvas.Top)"
Duration="0:0:4"
From="110" To="-80"
RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>
</Canvas>
...
Das komplette Beispiel kann hier heruntergeladen werden:




Echt cool!
Und sinnlos ist das ganz und gar nicht:
1. Hat man viel dazu gelernt, wie man so etwas umsetzt (wäre mir auf Anhieb nicht eingefallen).
2. Man kann auch Anwendungen bauen, bei denen unten ein kleines Eck fehlt, als kleinen optischen Pepp. Oder vielleicht Features nutzen wie in Office 2007 (Symbole in der Titelleiste), oder wie die neuen Adobe CS4 Produkte (komplettes Skin inkl. Titelleiste).
Und ob das einen Nutzen hat!!
Es hat soeben ein kleines Designproblem in unserer Anwendung behoben. Dort liegen Fenster übereinander, die aber nicht als eigenständige Fenster erkennbar sein sollen.
Danke dafür!
Danke für das Feedback! Wahrscheinlich werde ich es tatsächlich demnächst in einer realen Anwendung brauchen.
Cool, freut mich, dass es Dir geholfen hat!
hallo bernd,
so sinnlos ist das gar nicht.
ich kann dein Beispiel sehr gut gebrauchen
danke für dein Beispiel
gruß
Raimund
Danke für das Beispiel!
Stellt sich noch die Frage, ob man den VS-Designer dazu bringen kann, auch den Fensterrahmen auszublenden – anstatt nur zur Laufzeit…