基于WPF實現(xiàn)瀑布流控件
WPF 實現(xiàn)瀑布流控件
框架支持.NET4 至 .NET8;
Visual Studio 2022;
需求詳見 ISSUE

實現(xiàn)代碼
1)新增 WaterfallPanel.cs 代碼如下:
WaterfallPanel的自定義控件,繼承自VirtualizingPanel。WaterfallPanel控件實現(xiàn)了瀑布流布局,即將多個子元素按照一定規(guī)則排列在面板中。該控件具有Columns和Spacing兩個依賴屬性,分別表示列數(shù)和每個子控件之間的間距。MeasureOverride用于測量和排列子控件。在WaterfallPanel的MeasureOverride方法中,先清除了列高的記錄,然后計算出每一列的高度并保存在一個List中。接著,遍歷所有子控件,將它們測量并按規(guī)則排列在面板中,同時更新列高和面板的大小。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)示例(二)后臺添加代碼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實現(xiàn)瀑布流控件的文章就介紹到這了,更多相關(guān)WPF瀑布流控件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在Winform程序中使用Spire.Pdf實現(xiàn)頁面添加印章功能的實現(xiàn)
這篇文章主要介紹了在Winform程序中使用Spire.Pdf實現(xiàn)頁面添加印章功能的實現(xiàn),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09
C# WinForm捕獲全局變量異常 SamWang解決方法
本文將介紹C# WinForm捕獲全局變量異常 SamWang解決方法,需要的朋友可以參考2012-11-11
.Net WInform開發(fā)筆記(二)Winform程序運行結(jié)構(gòu)圖及TCP協(xié)議在Winform中的應(yīng)用
中午沒事,把去年剛畢業(yè)那會畫的幾張圖翻出來了,大概介紹Winform應(yīng)用程序運行的過程,以及TCP協(xié)議在Winform中的應(yīng)用。感興趣的朋友可以了解下;如果有Windows消息機制等基礎(chǔ),很好理解這兩張2013-01-01
詳解Unity使用ParticleSystem粒子系統(tǒng)模擬藥水在血管中流動(粒子碰撞)
這篇文章主要介紹了Unity使用ParticleSystem粒子系統(tǒng)模擬藥水在血管中流動(粒子碰撞),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-05-05

