基于WPF實(shí)現(xiàn)瀑布流控件
WPF 實(shí)現(xiàn)瀑布流控件
框架支持.NET4 至 .NET8;
Visual Studio 2022;
需求詳見(jiàn) ISSUE
實(shí)現(xiàn)代碼
1)新增 WaterfallPanel.cs
代碼如下:
WaterfallPanel
的自定義控件,繼承自VirtualizingPanel
。WaterfallPanel
控件實(shí)現(xiàn)了瀑布流布局,即將多個(gè)子元素按照一定規(guī)則排列在面板中。該控件具有Columns
和Spacing
兩個(gè)依賴(lài)屬性,分別表示列數(shù)和每個(gè)子控件之間的間距。MeasureOverride
用于測(cè)量和排列子控件。在WaterfallPanel
的MeasureOverride
方法中,先清除了列高的記錄,然后計(jì)算出每一列的高度并保存在一個(gè)List
中。接著,遍歷所有子控件,將它們測(cè)量并按規(guī)則排列在面板中,同時(shí)更新列高和面板的大小。AddChild
方法向面板中添加子控件。
using System; using System.Collections.Generic; using System.Linq; using System.Windows.Controls; using System.Windows; namespace WPFDevelopers.Controls { public class WaterfallPanel : VirtualizingPanel { private List<double> columnHeights = new List<double>(); protected override Size MeasureOverride(Size availableSize) { columnHeights.Clear(); var panelDesiredSize = new Size(0, 0); columnHeights = new double[Columns].ToList(); double currentX = 0; var width = availableSize.Width / Columns - (Columns * Spacing); for (int i = 0; i < InternalChildren.Count; i++) { var child = InternalChildren[i] as FrameworkElement; if (child == null) continue; child.Measure(availableSize); child.Width = width; int columnIndex = i % Columns; double x = columnIndex != 0 ? currentX + Spacing : 0; double y = columnHeights[columnIndex]; if (i >= Columns) y = y + Spacing; var size = new Size(width, child.DesiredSize.Height); child.Arrange(new Rect(new Point(x, y), size)); panelDesiredSize.Width = Math.Max(panelDesiredSize.Width, x + child.DesiredSize.Width); panelDesiredSize.Height = Math.Max(panelDesiredSize.Height, y + child.DesiredSize.Height); currentX = x + size.Width; if (currentX >= Width) currentX = 0; columnHeights[columnIndex] += child.DesiredSize.Height + (i >= Columns ? Spacing : 0); } return panelDesiredSize; } public void AddChild(UIElement element) { Children.Add(element); } public int Columns { get { return (int)GetValue(ColumnsProperty); } set { SetValue(ColumnsProperty, value); } } public static readonly DependencyProperty ColumnsProperty = DependencyProperty.Register("Columns", typeof(int), typeof(WaterfallPanel), new PropertyMetadata(3)); public double Spacing { get { return (double)GetValue(SpacingProperty); } set { SetValue(SpacingProperty, value); } } public static readonly DependencyProperty SpacingProperty = DependencyProperty.Register("Spacing", typeof(double), typeof(WaterfallPanel), new PropertyMetadata(5.0)); } }
2)示例(一)代碼WaterfallPanelExample.xaml
如下:
<ScrollViewer> <wd:WaterfallPanel Width="750"> <wd:WaterfallPanel.Resources> <Style TargetType="Border"> <Setter Property="CornerRadius" Value="10" /> <Setter Property="BorderBrush" Value="LightGray" /> <Setter Property="BorderThickness" Value="1" /> </Style> <Style TargetType="ImageBrush"> <Setter Property="Stretch" Value="Fill" /> </Style> <Style TargetType="TextBlock"> <Setter Property="Margin" Value="4,10" /> <Setter Property="Foreground" Value="White" /> </Style> <Style x:Key="BorderContent" TargetType="Border"> <Setter Property="Height" Value="40" /> <Setter Property="CornerRadius" Value="10,10,0,0" /> <Setter Property="VerticalAlignment" Value="Top" /> <Setter Property="Background"> <Setter.Value> <LinearGradientBrush Opacity=".3" StartPoint="0,.5" EndPoint="0,1"> <GradientStop Offset="0" Color="DimGray" /> <GradientStop Offset="0.9" Color="Gray" /> <GradientStop Offset="1" Color="Transparent" /> </LinearGradientBrush> </Setter.Value> </Setter> </Style> </wd:WaterfallPanel.Resources> <Border Height="340"> <Border.Background> <ImageBrush ImageSource="http://tse2-mm.cn.bing.net/th/id/OIP-C.WVAYTzW5VMZgAErg-y6EgwAAAA" /> </Border.Background> <Border Style="{StaticResource BorderContent}"> <TextBlock Text="WVAYTzW5VMZgAErg" /> </Border> </Border> <Border Height="300"> <Border.Background> <ImageBrush ImageSource="http://tse1-mm.cn.bing.net/th/id/OIP-C.e51iwDiqzatju6Bf50lJ2QHaMW" /> </Border.Background> <Border Style="{StaticResource BorderContent}"> <TextBlock Text="e51iwDiqzatju6Bf50lJ2QHaMW" /> </Border> </Border> <Border Height="280"> <Border.Background> <ImageBrush ImageSource="http://tse1-mm.cn.bing.net/th/id/OIP-C.dB2fWdfqfr8w3sP7wiboHgHaNK" /> </Border.Background> <Border Style="{StaticResource BorderContent}"> <TextBlock Text="dB2fWdfqfr8w3sP7wiboHgHaNK" /> </Border> </Border> <Border Height="350"> <Border.Background> <ImageBrush ImageSource="http://tse4-mm.cn.bing.net/th/id/OIP-C.IzGLt2NgGhakuvbk008FOwHaK9" /> </Border.Background> <Border Style="{StaticResource BorderContent}"> <TextBlock Text="IzGLt2NgGhakuvbk008FOwHaK9" /> </Border> </Border> <Border Height="400"> <Border.Background> <ImageBrush ImageSource="http://pic4.zhimg.com/v2-6233e57a364dcb3b6c5f066f8b30dab4_r.jpg" /> </Border.Background> <Border Style="{StaticResource BorderContent}"> <TextBlock Text="6233e57a364dcb3b6c5f066f8b30dab4_r" /> </Border> </Border> <Border Height="240"> <Border.Background> <ImageBrush ImageSource="http://tse1-mm.cn.bing.net/th/id/OIP-C.ivs2k5Q7Zx7WRZVuSDUJqQHaJ4" /> </Border.Background> <Border Style="{StaticResource BorderContent}"> <TextBlock Text="ivs2k5Q7Zx7WRZVuSDUJqQHaJ4" /> </Border> </Border> <Border Height="290"> <Border.Background> <ImageBrush ImageSource="http://tse3-mm.cn.bing.net/th/id/OIP-C.sTVQljOS9ntgkUyvDXk68AHaKe" /> </Border.Background> <Border Style="{StaticResource BorderContent}"> <TextBlock Text="sTVQljOS9ntgkUyvDXk68AHaKe" /> </Border> </Border> <Border Height="207"> <Border.Background> <ImageBrush ImageSource="http://tse2-mm.cn.bing.net/th/id/OIP-C.caVFPs_YGiHH-7vOpQ7GqwHaHY" /> </Border.Background> <Border Style="{StaticResource BorderContent}"> <TextBlock Text="7vOpQ7GqwHaHY" /> </Border> </Border> <Border Height="200"> <Border.Background> <ImageBrush ImageSource="http://tse2-mm.cn.bing.net/th/id/OIP-C.T_Zi1o-AYSCp4c00D_zCVAHaHa" /> </Border.Background> <Border Style="{StaticResource BorderContent}"> <TextBlock Text="AYSCp4c00D_zCVAHaHa" /> </Border> </Border> <Border Height="220"> <Border.Background> <ImageBrush ImageSource="http://tse2-mm.cn.bing.net/th/id/OIP-C.-EGv7Ycl5Zu46_YIGjNuDgHaH4" /> </Border.Background> <Border Style="{StaticResource BorderContent}"> <TextBlock Text="EGv7Ycl5Zu46_YIGjNuDgHaH4" /> </Border> </Border> <Border Height="200"> <Border.Background> <ImageBrush ImageSource="http://tse4-mm.cn.bing.net/th/id/OIP-C.TQ1f0BMQ7Bo7PuRKnCJAMAHaHa" /> </Border.Background> <Border Style="{StaticResource BorderContent}"> <TextBlock Text="TQ1f0BMQ7Bo7PuRKnCJAMAHaHa" /> </Border> </Border> <Border Height="450"> <Border.Background> <ImageBrush ImageSource="http://img.zcool.cn/community/01493f5d11d9cca801205e4b24e764.jpg" /> </Border.Background> <Border Style="{StaticResource BorderContent}"> <TextBlock Text="01493f5d11d9cca801205e4b24e764" /> </Border> </Border> </wd:WaterfallPanel> </ScrollViewer>
3)示例(二)后臺(tái)添加代碼WaterfallPanelExample.xaml.cs
如下:
var ran = new Random(); for (int i = 0; i < 1000; i++) { var btn = new Button { Content = i.ToString(), Height = (double)ran.Next(100, 1000) }; MyWaterfallPanel.AddChild(btn); }
效果圖
到此這篇關(guān)于基于WPF實(shí)現(xiàn)瀑布流控件的文章就介紹到這了,更多相關(guān)WPF瀑布流控件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在Winform程序中使用Spire.Pdf實(shí)現(xiàn)頁(yè)面添加印章功能的實(shí)現(xiàn)
這篇文章主要介紹了在Winform程序中使用Spire.Pdf實(shí)現(xiàn)頁(yè)面添加印章功能的實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09c#強(qiáng)制類(lèi)型轉(zhuǎn)換int方式
這篇文章主要介紹了c#強(qiáng)制類(lèi)型轉(zhuǎn)換int方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07C# WinForm捕獲全局變量異常 SamWang解決方法
本文將介紹C# WinForm捕獲全局變量異常 SamWang解決方法,需要的朋友可以參考2012-11-11.Net WInform開(kāi)發(fā)筆記(二)Winform程序運(yùn)行結(jié)構(gòu)圖及TCP協(xié)議在Winform中的應(yīng)用
中午沒(méi)事,把去年剛畢業(yè)那會(huì)畫(huà)的幾張圖翻出來(lái)了,大概介紹Winform應(yīng)用程序運(yùn)行的過(guò)程,以及TCP協(xié)議在Winform中的應(yīng)用。感興趣的朋友可以了解下;如果有Windows消息機(jī)制等基礎(chǔ),很好理解這兩張2013-01-01詳解Unity使用ParticleSystem粒子系統(tǒng)模擬藥水在血管中流動(dòng)(粒子碰撞)
這篇文章主要介紹了Unity使用ParticleSystem粒子系統(tǒng)模擬藥水在血管中流動(dòng)(粒子碰撞),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-05-05