C# utilise DataGridView pour simuler le dessin

  Nous avons reçu une demande pour dessiner une image d'une canalisation d'eau. Ce type de canalisation peut avoir 12 méthodes de segmentation. Enfin, ces 12 méthodes de segmentation sont combinées et affichées sur une canalisation d'eau. Les exigences sont :

  ⒈Prise en charge de l'affichage des attributs segmentés ;

  ⒉ Chaque segment doit être clairement affiché, le nombre de segments est compris entre 0 (pas de segments) et 100, et la longueur de la conduite d'eau est variable ;

  3. Chaque attribut de segment a une valeur, peut être modifié et est stocké au format XML ;

  4. Différents pipelines de matériaux utilisent différents arrière-plans ;

  5. Affichez différentes couleurs dans des segments selon différentes valeurs ;

  6. Prise en charge du défilement de la souris.

  Parce qu'il fallait le terminer rapidement et que le temps était compté, j'ai immédiatement pensé à utiliser le GDI+ de C#, mais je suis resté bloqué lors de la prise en charge des hotspots et des zooms avant et arrière. J'ai rapidement changé de méthode et développé un contrôle personnalisé pour dessiner sur le panneau et prendre en charge en faisant glisser. , zoomer et dézoomer, mais il y a toujours des problèmes comme celui-ci. Je veux aussi utiliser SVG, mais je crains qu'il ne soit toujours pas terminé. Je l'ai donc changé en DataGridView et il est terminé. L'effet est comme suit:

  Je vois souvent sur Internet qu'on ne peut pas écrire de code après 35 ans en Chine. J'ai l'impression que l'une est parce que je n'ai pas assez d'amour pour cela, et l'autre est que ma condition physique ne le permet pas. Dans les entreprises ordinaires, il n'y a pas de motivation pour terminer un programme comme quand j'étais jeune. À cette époque, j'avais le dynamisme et le dynamisme, j'étais particulièrement patient et je voulais être reconnu et félicité par les autres. Aujourd'hui, j'ai plus de 50 ans. ans, et je n'ai aucune motivation. Pensez au passé. Moi aussi, je trouve ça ridicule.

  Une fois cette opération terminée, un contrôle personnalisé peut être utilisé.

   Voici le code terminé :

  définition:

        private static ToolTip toolTip = new ToolTip();
        // 定义一个List,用于存储点的信息
        List<float> Points = new List<float>() {0 };

        int MinColWidth=48;//定义最小分段对应的宽度
        float pipelineLength;//定义管线长度
        float RateF;//实际进行计算的比例 

  initialisation :

            //初始化DataGridView
            dataGridView1.ColumnHeadersVisible = false;//隐藏标题栏          
            dataGridView1.CellBorderStyle = DataGridViewCellBorderStyle.None;//取消分割线
            //dataGridView1.ScrollBars = ScrollBars.Horizontal;
            dataGridView1.ScrollBars = ScrollBars.None;//去掉滚动条
            dataGridView1.AllowUserToAddRows = false;//不允许用户增加行
            dataGridView1.AllowUserToDeleteRows = false;//不允许用户删除行
            dataGridView1.AllowUserToResizeRows = false;//不允许用户改变行高度
            //dataGridView1.Columns.Add("Column1", "列1");
            dataGridView1.RowTemplate.Height = 32;//设置行高度
            //dataGridView1.Rows.Add();
            //dataGridView1.Rows[0].DefaultCellStyle.BackColor = Color.LightGray;
            dataGridView1.AllowUserToResizeColumns = false;//不允许用户改变栏宽度
            dataGridView1.RowHeadersVisible = false;//隐藏最前面的选择列            
            dataGridView1.Columns.Clear();//删除所有的列            
            dataGridView1.Columns.Add("Column1", "列1");//添加一列
            dataGridView1.Rows.Add();//添加一行
            dataGridView1.Rows[0].ReadOnly = true;//设置第一行为只读
            dataGridView1.Rows[0].DefaultCellStyle.BackColor = Color.LightGray;//设置行背景色           
            dataGridView1.Columns[0].Visible = false;//隐藏标题栏
                                                     
            dataGridView1.EditMode = DataGridViewEditMode.EditProgrammatically;// 设置编辑模式为EditProgrammatically
            //注册事件
            dataGridView1.CellPainting += dataGridView1_CellPainting;//单元格渲染
            dataGridView1.CellFormatting += dataGridView1_CellFormatting;
            dataGridView1.MouseEnter += dataGridView1_MouseEnter;//鼠标移入
            dataGridView1.MouseLeave += dataGridView1_MouseLeave;//鼠标离开
            dataGridView1.MouseWheel += dataGridView1_MouseWheel;//鼠标滚动
            dataGridView1.RowPrePaint+=dataGridView1_RowPrePaint;//行渲染

            //List<float> P = new List<float>() { 12, 27, 41, 73, 89, 105, 119, 126, 138, 166, 192, 208, 255, 377, 410, 439 };
            List<float> P = new List<float>() { 31, 25, 45,39, 73, 89, 115, 121 };
            UpdatePoints(P, 138);

  Contenu des événements et des fonctions :

        void UpdatePoints(List<float> NewPoints,float NowDistance)
        {
            Points = NewPoints;
            pipelineLength = NowDistance;

            Points.Add(0);
            Points.Add(pipelineLength);
            Points.Sort();

            //计算实际的换算比例
            RateF = ((dataGridView1.Width - (Points.Count - 1) * 5) / pipelineLength);
            textBox1.Text += "计算比例:" + RateF.ToString() + Environment.NewLine;
            textBox1.Text += "管线长度:" + pipelineLength.ToString() + Environment.NewLine;
            textBox1.Text += "显示宽度:" + dataGridView1.Width.ToString() + Environment.NewLine;
            //得到最小的分段
            float MinSectionLength = CalculateMinDistance();
            textBox1.Text += "最小分段:" + MinSectionLength.ToString() + Environment.NewLine;
            if (MinSectionLength * RateF < MinColWidth)
            {
                //重新设定比例
                RateF = MinColWidth / MinSectionLength;
            }

            textBox1.Text += "最后比例:" + RateF.ToString() + Environment.NewLine;

            //更新DataGridView
            //设置每一列的宽度
            //foreach (int point in Points)
            for(int i=1; i<Points.Count; i++)
            {
               float ColWidth = (Points[i] - Points[i - 1]) * RateF;
                AddColumn(dataGridView1,"Section", (int)ColWidth,  Color.Brown, Color.Cyan, Points[i - 1], Points[i]);//增加分段
                if (i!=Points.Count-1)
                {
                    AddColumn(dataGridView1, "Dot", 5, Color.Brown, Color.Blue, Points[i - 1], Points[i]);//增加点
                }                
            }
        }

        // 动态增加列
        void AddColumn(DataGridView dataGridView, string StrType, int width, Color textColor, Color cellBackColor,float StartDot,float EndDot)
        {
            DataGridViewTextBoxColumn column = new DataGridViewTextBoxColumn();
            column.Width = width;
            //column.HeaderText = text;
            column.DefaultCellStyle.ForeColor = textColor;
            column.DefaultCellStyle.BackColor = cellBackColor;

            // 为每一列添加属性
            column.Tag = new ColumnProperty
            {
                SectionType = StrType,
                StartPoint = StartDot,
                EndPoint = EndDot,
                Distance = EndDot - StartDot
            };
            dataGridView.Columns.Add(column);
            // 获取第一行
            DataGridViewRow firstRow = dataGridView.Rows[0];

            // 设置特定列的单元格属性
            //firstRow.Cells[column.Index].Value = text;
            firstRow.Cells[column.Index].Style.BackColor = cellBackColor;
            firstRow.Cells[column.Index].Style.ForeColor = Color.Red;

            //dataGridView.Columns.Add(column);
        }

        class ColumnProperty
        {
            public int SectionIndex { get; set; }   //分段序号
            public string SectionType { get; set; } //类型
            public float StartPoint { get; set; }  //起点
            public float EndPoint { get; set; }    //终点
            public float Distance { get; set; }      //距离
            public string Rule01 { get; set; }      //
            public string Rule02 { get; set; }      //
            public string Rule03 { get; set; }      //
            public string Rule04 { get; set; }      //
            public string Rule05 { get; set; }      //
            public string Rule06 { get; set; }      //
            public string Rule07 { get; set; }      //
            public string Rule08 { get; set; }      //
            public string Rule09 { get; set; }      //
            public string Rule10 { get; set; }      //
            public string Rule11 { get; set; }      //
            public string Rule12 { get; set; }      //管理站队
            public float Pvalue { get; set; }       //失效可能性
            public float Cvalue { get; set; }       //风险
            public float Rvalue { get; set; }       //后果
        }
        
        float CalculateMinDistance()
        {
            // 实现计算功能,计算相邻两个点之间的距离,得到最小值
            List<float> segmentLengths = new List<float>();
            for (int i = 0; i < Points.Count - 1; i++)
            {
                float segmentLength = Points[i + 1] - Points[i];
                segmentLengths.Add(segmentLength);
            }
            float minSegmentLength = segmentLengths.Count > 0 ? segmentLengths.Min() : pipelineLength;
            return FloatFormat(minSegmentLength);
        }

        private float FloatFormat(float f)
        {
            return (float)Math.Round(f, 2); ;
        }

        private void dataGridView1_Scroll(object sender, ScrollEventArgs e)
        {
            // 判断是否是水平滚动
            if (e.ScrollOrientation == ScrollOrientation.HorizontalScroll)
            {
                // 水平滚动内容
                dataGridView1.HorizontalScrollingOffset = e.NewValue;
            }
        }

        private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            //if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
            //{
            //    if (e.ColumnIndex % 2 == 0)
            //    {
            //        e.CellStyle.BackColor = Color.DarkGray;
            //    }
            //    else
            //    {
            //        e.CellStyle.BackColor = Color.LightGray;
            //    }
            //}
        }

        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            //if (e.RowIndex >= 0 && e.ColumnIndex >= 0 && e.ColumnIndex % 2 == 0)
            //{
            //    dataGridView1.Rows[e.RowIndex].DefaultCellStyle.SelectionBackColor = Color.Transparent;
            //    dataGridView1.Rows[e.RowIndex].DefaultCellStyle.SelectionForeColor = dataGridView1.DefaultCellStyle.ForeColor;
            //}
        }

        private void dataGridView1_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
        {
            e.PaintParts &= ~DataGridViewPaintParts.Background;
            if (e.RowIndex >= 0)
            {
                Image image = Image.FromFile("D:/CSharp/TestTreeview/WinFormsApp2/WinFormsApp2/image/TRQpipeline.jpg"); // 替换为实际的图片路径
                Rectangle rect = new Rectangle(e.RowBounds.Left, e.RowBounds.Top, dataGridView1.Columns.GetColumnsWidth(DataGridViewElementStates.Visible) - 1, e.RowBounds.Height - 1);
                e.Graphics.DrawImage(image, rect);
            }
        }

        private void dataGridView1_MouseEnter(object sender, EventArgs e)
        {
            dataGridView1.BorderStyle = BorderStyle.FixedSingle;
            //dataGridView1.BorderColor = Color.Red;            
        }

        private void dataGridView1_MouseLeave(object sender, EventArgs e)
        {
            dataGridView1.BorderStyle = BorderStyle.None;
        }

        private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            //if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
            //{
            //    // 设置单元格背景颜色
            //    e.CellStyle.BackColor = Color.Red;

            //    // 设置单元格背景色的透明度
            //    e.CellStyle.BackColor = Color.FromArgb(192, e.CellStyle.BackColor);
            //}

            if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
            {
                if (e.ColumnIndex % 2 != 0)
                {
                    // 设置偶数列单元格的前景色为半透明背景色
                    using (Brush brush = new SolidBrush(Color.FromArgb(0, Color.White)))
                    {
                        e.Graphics.FillRectangle(brush, e.CellBounds);
                    }
                }
                else
                {
                    // 设置奇数列单元格的前景色为深灰色并覆盖行背景色
                    using (Brush brush = new SolidBrush(Color.Black))
                    {
                        e.Graphics.FillRectangle(brush, e.CellBounds);
                    }
                }

                // 绘制单元格内容
                e.PaintContent(e.CellBounds);
                e.Handled = true;
            }

        }

        // 处理鼠标滚轮事件
        private void dataGridView1_MouseWheel(object sender, MouseEventArgs e)
        {
            int delta = e.Delta;
            int newOffset = dataGridView1.HorizontalScrollingOffset - delta;

            // 检查滚动范围是否超出边界
            if (newOffset < 0)
            {
                newOffset = 0; // 将滚动范围限制在最左边
            }
            else if (newOffset > GetHorizontalScrollingOffsetMax())
            {
                newOffset = GetHorizontalScrollingOffsetMax(); // 将滚动范围限制在最右边
            }

            // 设置新的水平滚动偏移量
            dataGridView1.HorizontalScrollingOffset = newOffset;
        }


        private int GetHorizontalScrollingOffsetMax()
        {
            int maxOffset = 0;
            foreach (DataGridViewColumn column in dataGridView1.Columns)
            {
                maxOffset += column.Width;
            }
            maxOffset -= dataGridView1.ClientSize.Width;
            return maxOffset;
        }

        private void dataGridView1_CellMouseEnter(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex >= 0 && e.ColumnIndex % 2 != 0)
            {
                DataGridViewRow row = dataGridView1.Rows[e.RowIndex];
                ColumnProperty properties = (ColumnProperty)row.Cells[e.ColumnIndex].OwningColumn.Tag;
                string tooltip = $"Type: {properties.SectionType}\nStart Point: {properties.StartPoint}\nEnd Point: {properties.EndPoint}";
                toolTip.SetToolTip(dataGridView1, tooltip);
            }
            else
            {
                string tooltip = "";
                toolTip.SetToolTip(dataGridView1, tooltip);
            }
        }

        private void dataGridView1_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            //判断分段属性如果是Section
            if (e.RowIndex >= 0)
            {
                DataGridViewRow row = dataGridView1.Rows[e.RowIndex];
                ColumnProperty properties = (ColumnProperty)row.Cells[e.ColumnIndex].OwningColumn.Tag;
                if (properties.SectionType == "Section")
                {
                    MessageBox.Show(properties.StartPoint.ToString()+ "|"+properties.EndPoint.ToString());
                }
            }
        }

  La fonction est terminée, mais les détails doivent être améliorés ultérieurement, à savoir la mise à jour des valeurs d'attribut, principalement la synchronisation du contenu TreeView et XML, y compris le calcul automatique.

  

Je suppose que tu aimes

Origine blog.csdn.net/dawn0718/article/details/131756144
conseillé
Classement