C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > WPF瀑布流控件

基于WPF实现瀑布流控件

作者:WPF开发者

这篇文章主要介绍了如何基于WPF实现简单的瀑布流控件,文中的示例代码讲解详细,对我们的学习或工作有一定帮助,需要的小伙伴可以参考一下

WPF 实现瀑布流控件

框架支持.NET4 至 .NET8;

Visual Studio 2022;

需求详见 ISSUE

实现代码

1)新增 WaterfallPanel.cs 代码如下:

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);
}

效果图

到此这篇关于基于WPF实现瀑布流控件的文章就介绍到这了,更多相关WPF瀑布流控件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文