WPF實現不規則窗體,方法很多很多多....
本文總結DebugLZQ認為簡潔高效的幾種方法
實現WPF不規則窗體的幾種常用的方法如下:
1.使用Blend等工具繪制一想要的窗體。這個可以參考xiaowei0705的這篇博文:WPF制作不規則的窗體 。
2.給window的Clip屬性賦Path值。這個可以參考DebugLZQ前面的博文:WPF Effect Clip以及Transform 。
3.使用透明背景的PNG圖像。
4.為Window主容器添加Border
5.使用Blender制作想要的Path的說明。
6.其他
本文將要講述的第一種方法,可以說一點技術含量都沒有,基本不用動手編寫代碼。前提是你得有合適的透明背景的PNG圖像。
我們假設你已經完成了PNG圖像的制作(當然為了演示的話,down一個也行),那么這個不規則窗體實現如下:
<Window x:Class="WPFSharpWindow.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="412" Width="528" AllowsTransparency="True" WindowStyle="None" OpacityMask="White" Background="Transparent"> <Grid MouseLeftButtonDown="Grid_MouseLeftButtonDown"> <Image Stretch="Fill" Source="/WPFSharpWindow;component/cow.png" /> </Grid> </Window>
解釋下這個xaml需要注意的屬性設置:
allowstransparency="True"
- 允許透明
background="Transparent"
- 設置背景透明
windowstyle="None"
- 去掉邊框
opacitymask="White"
- 設置白色透明
為Gird訂閱的MouseLeftButtonDown路由事件,是為了實現窗體的拖動。事件處理如下:
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { this.DragMove(); }
實現效果如下:
效果不清楚?再來兩張
題外話:越來越發現發到博客園首頁的博文質量是越來越差了,很多文章根本沒有一點價值,純垃圾~
真心建議發到首頁的博文,希望博文的作者能夠花點時間,分享有價值的東西,不要嘩眾取寵~試想:你發到首頁的博文你自己以后都不願意去看的,何況別人?也希望博客園團隊加強監管力度!
我們寫博文的目的是為了分享,分享本來就是一種積累,寫博文的過程可以看做是一種沉淀,所以這是一個雙贏的事。個人愚見,歡迎批評指正~
“只要人人都獻出一點愛,世界將變成美好的人間...”
-------------
需要運行時更新窗體樣式怎么辦?即更新圖片即可:
private void button1_Click(object sender, RoutedEventArgs e) { var uriSource = new Uri(@"/WPFSharpWindow;component/HotPot.png", UriKind.Relative); imgBackground.Source=new BitmapImage(uriSource); }
4. 為Window主容器添加Border
和前面DebugLZQ博文使用Clip屬性類似,我們可以為Window的頂層容器添加Border來實現。
這種方法,對Border的編寫有要求,而對其使用的Image、容器內容等沒有要求。
下面給出一個例子
MainWindow.xaml如下:
<Window x:Class="WPFWindowAnimation.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525" AllowsTransparency="True" WindowStyle="None" Background="Transparent" MouseLeftButtonDown="Window_MouseLeftButtonDown"> <Border CornerRadius="0,30,40,50" Width="Auto" Height="Auto" BorderThickness="1" BorderBrush="Green"> <Border.Background> <ImageBrush ImageSource="Tulips.jpg"/> </Border.Background> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition /> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Margin="5" Text="Title" /> <Grid Grid.Row="1" /> <TextBlock Margin="1,10,1,1" Grid.Row="2" Text="Footer" Padding="5" HorizontalAlignment="Center"/> </Grid> </Border> </Window>
效果如下:
當然,如果我只是期待的是一個顏色背景的話,可以直接設置Border的Fill屬性來獲得。
tip1:關於窗口的DragMove:只要在MouseLeftButtonDown事件中調用this.DragMove();
tip2:關於窗口的Resize:通過設置Window的屬性:如ResizeMode="CanResizeWithGrip"來實現。
tip3:關於窗口的關閉、最大化、最小化等:通過在容器中添加Button,為其添加合適的樣式,通過Button的Click事件來實現。
this.Close();
this.WindowState = System.Windows.WindowState.Maximized;
this.WindowState = System.Windows.WindowState.Minimized;
5.方法1,2的實現關鍵---Path的制作
這個方法1,2中都沒有講述Path是如何制作的,因此這里有必要再說明下:
制作Path一般有2中方法:
1.使用所謂的"路徑描述語言",即Path的包含有M、L、C、Z等Data屬性值的書寫方式。這種方法的優點是Path描述干凈清爽;缺點是實現方法相對復雜一點。
2.使用Blender。缺點是Path描述復雜;但優點是使用方便,能“拖拽”出各種Path。
下面我們使用Blender來制作1個Path。
我們向Window上添加1個Rectangle和1個Triangle.
拖動調整下,如下:
注意此時,生成的xaml並不是Path。
把這兩個Element組合起來,如下:
則效果如下:
此時,生成的xaml已經是Path了。
------------------
也可先生成Path
然后把生成的2個Path組合起來,效果和上面相同。
當然也可以選中頁面元素右擊,....,這些都是Blend的具體操作了,不是本文的主要說明對象~
----------------------
然后就可以使用這個Path,來方便的制作Path型的窗體了。如下:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WPFNavigationPanelPro" xmlns:ec="http://schemas.microsoft.com/expression/2010/controls" xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing" x:Class="WPFNavigationPanelPro.MainWindow" Title="MainWindow" Height="444" Width="559" WindowStyle="None" AllowsTransparency="True" Background="Transparent"> <Grid> <Path Data="M137.333,1 L167.333,31.000003 277.333,31.000003 277.333,177.33299 1,177.33299 1,31.000003 107.333,31.000003 z" Fill="Green" Margin="102.667,16,106,84.117" Stretch="Fill" Stroke="Transparent" StrokeThickness="2"/> <WrapPanel Margin="115,94,119,116"> <Rectangle Fill="Red" Width="60" Height="40" Margin="10"/> <Rectangle Fill="Red" Width="60" Height="40" Margin="10"/> <Rectangle Fill="Red" Width="60" Height="40" Margin="10"/> <Rectangle Fill="Red" Width="60" Height="40" Margin="10"/> <Rectangle Fill="Red" Width="60" Height="40" Margin="10"/> </WrapPanel> </Grid> </Window>
運行效果如下:
(說明:之所以做成Path是因為:簡潔一點。完全可以拖出來想要的界面直接使用~)
又如:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="WindowTest.MainWindow" x:Name="Window" Title="MainWindow" Width="640" Height="552" WindowStyle="None" AllowsTransparency="True" Background="Transparent"> <Grid x:Name="LayoutRoot"> <Path Data="M144,0.5 C220.77621,0.5 283.46991,22.348854 287.31326,49.824082 L287.38416,50.5 287.5,50.5 287.5,52.499997 287.5,232.5 C287.5,251.27768 223.25287,266.5 144,266.5 64.747139,266.5 0.5,251.27768 0.5,232.5 L0.5,52.499997 0.5,50.5 0.61584973,50.5 0.6867221,49.824082 C4.5301003,22.348854 67.223793,0.5 144,0.5 z" Stretch="Fill" Stroke="Black" Opacity="0.5" Margin="0,0,0,1"> <Path.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Offset="0" Color="Violet"/> <GradientStop Offset="1" Color="LightGreen"/> </LinearGradientBrush> </Path.Fill> </Path> <Border BorderBrush="Pink" BorderThickness="1" Margin="0,102,0,69" Opacity="0.3"> <Grid Margin="8,106.5,8,72.5" /> </Border> </Grid> </Window>
效果如下:
通過Blend可以制作出你能想到的各種所謂不規則窗體~
6.其他
小結:在各種方法實現WPF不規則窗體的方法種,Blender來制作Path這種方法最靈活強大~
Wish it helps.