WPF dynamically generate grid with calculated rows and columns, put the custom control in the specified cell of grid and never overlap or intersect

复制代码
private void FillGridRandomly()
{
    rowsColsSet = new HashSet<XY>();
    if (gd != null)
    {
        gd.Children.Clear();
    }


    for (int i = 0; i < 50; i++)
    {
        while (true)
        {
            XY xy = new XY();
            xy.X = rnd.Next(0, rowsCount);
            xy.Y = rnd.Next(0, columnsCount);
            if (!rowsColsSet.Contains(xy))
            {
                rowsColsSet.Add(xy);
                ElpImageTbk elpImg = new ElpImageTbk();
                elpImg.Width = 100;
                elpImg.Height = 50;
                BitmapImage bmp = new BitmapImage();
                bmp.BeginInit();
                bmp.UriSource=new Uri(imgsList[i%imgsCount], UriKind.RelativeOrAbsolute);
                bmp.EndInit();
                bmp.Freeze();
                elpImg.UCElpImgBrush=new ImageBrush(bmp);
                elpImg.UCStr = (i + 1).ToString();
                Grid.SetRow(elpImg, xy.X);
                Grid.SetColumn(elpImg, xy.Y);
                if (!gd.Children.Contains(elpImg))
                {
                    gd.Children.Add(elpImg);
                }
                break;
            }
        }
    }
}
复制代码

 

 

 

 

 

 

 

 

 

复制代码
//custom control.xaml
<UserControl x:Class="WpfApp390.ElpImageTbk"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApp390"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Ellipse Fill="{Binding UCElpImgBrush,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
        <TextBlock Text="{Binding UCStr,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center"
                   FontSize="50"
                   Foreground="Red"/>
    </Grid>
</UserControl>


//custom control.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp390
{
    /// <summary>
    /// Interaction logic for ElpImageTbk.xaml
    /// </summary>
    public partial class ElpImageTbk : UserControl
    {
        public ElpImageTbk()
        {
            InitializeComponent();
            this.DataContext = this;
        }



        public ImageBrush UCElpImgBrush
        {
            get { return (ImageBrush)GetValue(UCElpImgBrushProperty); }
            set { SetValue(UCElpImgBrushProperty, value); }
        }

        // Using a DependencyProperty as the backing store for UCElpImgBrush.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty UCElpImgBrushProperty =
            DependencyProperty.Register("UCElpImgBrush", typeof(ImageBrush),
                typeof(ElpImageTbk), new PropertyMetadata(null));





        public string UCStr
        {
            get { return (string)GetValue(UCStrProperty); }
            set { SetValue(UCStrProperty, value); }
        }

        // Using a DependencyProperty as the backing store for UCStr.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty UCStrProperty =
            DependencyProperty.Register("UCStr", typeof(string),
                typeof(ElpImageTbk), new PropertyMetadata(""));



    }
}


//cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp390
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private Random rnd { get; set; }
        private int width { get; set; }
        private int height { get; set; }
        private Grid gd { get; set; }
        private int rowsCount { get; set; }
        private int columnsCount { get; set; }
        private System.Timers.Timer tmr { get; set; }
        HashSet<XY> rowsColsSet { get; set; }
        private List<string> imgsList { get; set; }
        private int imgsCount { get; set; }

        public MainWindow()
        {
            InitializeComponent();
            this.WindowState = WindowState.Maximized;
            this.Loaded += MainWindow_Loaded;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            InitVariables();
            tmr = new System.Timers.Timer();
            tmr.Elapsed += Tmr_Elapsed;
            tmr.Interval = 2000;
            tmr.Start();
        }

        private void Tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Application.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                FillGridRandomly();
            }));
        }

        private void FillGridRandomly()
        {
            rowsColsSet = new HashSet<XY>();
            if (gd != null)
            {
                gd.Children.Clear();
            }


            for (int i = 0; i < 50; i++)
            {
                while (true)
                {
                    XY xy = new XY();
                    xy.X = rnd.Next(0, rowsCount);
                    xy.Y = rnd.Next(0, columnsCount);
                    if (!rowsColsSet.Contains(xy))
                    {
                        rowsColsSet.Add(xy);
                        ElpImageTbk elpImg = new ElpImageTbk();
                        elpImg.Width = 100;
                        elpImg.Height = 50;
                        BitmapImage bmp = new BitmapImage();
                        bmp.BeginInit();
                        bmp.UriSource=new Uri(imgsList[i%imgsCount], UriKind.RelativeOrAbsolute);
                        bmp.EndInit();
                        bmp.Freeze();
                        elpImg.UCElpImgBrush=new ImageBrush(bmp);
                        elpImg.UCStr = (i + 1).ToString();
                        Grid.SetRow(elpImg, xy.X);
                        Grid.SetColumn(elpImg, xy.Y);
                        if (!gd.Children.Contains(elpImg))
                        {
                            gd.Children.Add(elpImg);
                        }
                        break;
                    }
                }
            }
        }

        private void InitVariables()
        {
            imgsList = System.IO.Directory.GetFiles(@"../../Images")?.ToList();
            if(imgsList==null || !imgsList.Any())
            {
                return;
            }
            imgsCount = imgsList.Count;
            rnd = new Random();
            width = (int)this.ActualWidth;
            height = (int)this.ActualHeight;
            columnsCount = width / 100;
            rowsCount = height / 50;
            gd = new Grid();
            gd.ShowGridLines = true;
            for (int i = 0; i < rowsCount; i++)
            {
                RowDefinition row = new RowDefinition();
                gd.RowDefinitions.Add(row);
            }
            for (int i = 0; i < columnsCount; i++)
            {
                ColumnDefinition col = new ColumnDefinition();
                gd.ColumnDefinitions.Add(col);
            }
            this.Content = gd;
        }
    }

    public struct XY
    {
        public int X { get; set; }

        public int Y { get; set; }
    }
}
复制代码

 

posted @   FredGrit  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示