Avatar billede ahara Nybegynder
04. juli 2006 - 21:44 Der er 16 kommentarer og
1 løsning

Tegnefunktion i C#

Hvis jeg ønsker et grid på f.eks. 5 x 5 felter og skal kunne udfylde de felter der klikkes i med en farve hvad vil i så anbefale jeg bruger?

Skal jeg benytte 5 x 5 pictureboxes eller f.eks. et panel?

Tak
AHR
Avatar billede md_craig Nybegynder
04. juli 2006 - 22:34 #1
Ville lave en controll til det...

og bruge OnPaint sammen med en af de Mouse events der er:
- MouseDown
- MouseUp
- MouseClick

OnPaint:
protected override void OnPaint(PaintEventArgs pe)
{
  Graphics g = pe.Graphics;
  //tegn her
}

...
på de forskellige events kan du få kordinater for hver der er klikket og så bestemme hvilket felt der skal farves... osv...
Avatar billede ahara Nybegynder
04. juli 2006 - 22:58 #2
Hvilken controll?
Avatar billede ahara Nybegynder
04. juli 2006 - 23:06 #3
Altså jeg mener hvad du ville tegne på. Er det på formen eller flere pictureboxes eller?
Avatar billede md_craig Nybegynder
05. juli 2006 - 00:27 #4
Det er basis for fx en form ja.. en knap osv... du kan lave CustomControlls direkte fra VS hvis det er det du arbejder i...

Så istedet for når du laver en for og du arver fra System.Windows.Forms.Form
Så arver du sitedet fra System.Windows.Forms.Control
Avatar billede md_craig Nybegynder
05. juli 2006 - 01:00 #5
Her er et udgangspunkt:

GridControl.cs
-------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace ChrExcample
{
    public partial class GridControl : Control
    {
        private int spacer;
        private List<Rectangle> active;

        public int Spacer
        {
            get { return spacer; }
            set { spacer = value; }
        }

        public GridControl()
        {
            InitializeComponent();

            this.active = new List<Rectangle>();
            this.spacer = 10;
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            Graphics g = pe.Graphics;

            using (Pen pBlack = new Pen(Color.FromArgb(0, 0, 0), 1))
            {
                pBlack.DashStyle = DashStyle.Dot;
               
                for (int i = 0; i < (int)this.Height / this.spacer; i++)
                    g.DrawLine(pBlack, new Point(0, (i * spacer) + spacer), new Point(this.Width, (i * spacer) + spacer));

                for (int i = 0; i < (int)this.Width / this.spacer; i++)
                    g.DrawLine(pBlack, new Point((i * spacer) + spacer, 0), new Point((i * spacer) + spacer, this.Height));
            }

            using (SolidBrush sbRed = new SolidBrush(Color.Red))
            {
                foreach (Rectangle r in active)
                {
                    g.FillRectangle(sbRed, r);
                }
            }

            base.OnPaint(pe);
        }

        private void GridControl_MouseClick(object sender, MouseEventArgs e)
        {
            Rectangle r = new Rectangle();
            r.X = ((e.X / this.spacer) * this.spacer)+1;
            r.Y = ((e.Y / this.spacer) * this.spacer)+1;
            r.Size = new Size(spacer-1, spacer-1);
            this.active.Add(r);
            this.Refresh();
        }
    }
}
-------------------------------------------------------------------------------------

GridControl.Designer.cs
-------------------------------------------------------------------------------------
namespace ChrExcample
{
    partial class GridControl
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.SuspendLayout();
            //
            // GridControl
            //
            this.Size = new System.Drawing.Size(100, 100);
            this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.GridControl_MouseClick);
            this.ResumeLayout(false);

        }

        #endregion
    }
}
-------------------------------------------------------------------------------------

Ved ikke lige om du kører 1.1 eller 2.0... men principet er det samme, men hvis det er .NET 1.1 skal du lige samle de to klasser da det ikke understøttede partial classes... eller det mener jeg hvertfald ikke det gjorde...

Så skal alt indhold fra GridControl.Designer.cs lige kastes ind i den anden fil... altså indeholdet af de brackets der indeholder koden til klassen, klasse definotionen og namespace definition skal ikke med...
Avatar billede md_craig Nybegynder
05. juli 2006 - 01:04 #6
En af de ting der er smarte ved dette, er at (Hvis du får din controll lavet korrekt, dvs. med default constructor mm. så kan du faktisk bruge den fra din toolbox, dvs. trække den direkte ind på en form som du måske er vandt til med en alm. knap, en textbox eller whatever... (igen befinder vi os i Visual Studio, men vil tro andre IDE'er også understøtter den slags, men har ikke arbejdet i andre IDE'er til .NET)
Avatar billede ahara Nybegynder
06. juli 2006 - 09:41 #7
Tak for dine svar md_craig, men er ikke helt sikker på hvad du mener. Indtil videre har jeg brugt et grid på 10 x 10 pictureBoxes. Når jeg trykker på en pictureBox bliver den sort og når jeg så benytter mouseMove skal den tegne på de andre picture boxes der køres over "det sidste virker dog ikke".

Ved du hvad jeg kan gøre?

********************
Her er min kode
********************

        private void Form1_Load(object sender, System.EventArgs e)
        {
            int panelHeight = panel1.Size.Height;
            int panelWidth = panel1.Size.Width;
            int gridSize = 20;
            pbList = new PictureBox[gridSize,gridSize];

            for(int i=0;i<gridSize;i++)
            {
                for(int j=0;j<gridSize;j++)
                {
                    PictureBox pb = new PictureBox();                   
                    pb.Height = panelHeight/gridSize;
                    pb.Width = panelWidth/gridSize;
                    pb.BorderStyle = BorderStyle.None;

                    pb.Location = new System.Drawing.Point(i*pb.Width, j*pb.Height);
                    pb.BackColor = System.Drawing.Color.White;
EventHandler(this.pictureClick);
                    pb.MouseDown += new MouseEventHandler(this.mouseDown);
                    pb.MouseUp += new MouseEventHandler(this.mouseUp);

EventHandler(this.mouseEnter);
                    pb.MouseMove += new MouseEventHandler(this.mouseMove);
                    pbList[i,j] = pb;

                    this.panel1.Controls.Add(pb);   
                }
            }
        }

        private void mouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            drawNow = true;
            label1.Text = "mouseDown";
        }

        private void mouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            drawNow = false;
            label1.Text = "mouseUp";
        }

        private void mouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            //if (drawNow==true)
            {
                                int gridSize = 20;
                label1.Text = "Drawing";

                int location = ((PictureBox)sender).Parent.Controls.GetChildIndex(((PictureBox)sender));
                int y = location % gridSize;
                int x = (location-y)/gridSize;

                pbList[x,y].BackColor = Color.Black;
            }
        }
Avatar billede ahara Nybegynder
06. juli 2006 - 09:42 #8
Sorry, men nedenstående skulle ikke være kopieret med ind:

EventHandler(this.pictureClick);
EventHandler(this.mouseEnter);
Avatar billede md_craig Nybegynder
06. juli 2006 - 10:50 #9
For lige at prøve at forklare hvad Controls er vil jeg lige liste nogle af dem op du nok bruger ofte...

System.Windows.Forms.Form
System.Windows.Forms.Buttom
System.Windows.Forms.TextBox

De har alle et eller andet sted i deres arveheraki System.Windows.Forms.Control.

Her er så lige et par Screenshots af hvordan det kunne se ud:
http://dotjem.com/GridControlA.png
http://dotjem.com/GridControlB.png

Det der kan være lidt smart, er at som du kan se bruger jeg den GridControl klasse på samme måde som med andre Controls, ved simpel Drag & Drop ind på min form...
Der kan jeg placere den hvor jeg vil, sætte størelsen på den, sætte hvor meget der skal være mellem hver linie i mit grid og en del andre ting...

For at oprette en ny Control i fx Visual Studio 2005 kan du gøre følgende:

1. Højreklik på dit projekt i din Solution Explorer
2. Vælg Add -> New Item
3. Find den template der heder "Custom Control"

Eller

1. Klik på Project i menulinien
2. Vælg Add new item
3. Find den template der heder "Custom Control"

Så giver den dig automatisk basisen for din nye Control... Dvs OnPaint metoden ect.

Her er igen lidt nyt kode... som gør lidt ala det deu vil i det nye spm.

-------------------------------------------------------------------------------------

GridControl.cs
-------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace ChrExcample
{
    public partial class GridControl : Control
    {
        private int spacer;
        private List<Rectangle> active;

        public int Spacer
        {
            get { return spacer; }
            set { spacer = value; }
        }

        public GridControl()
        {
            InitializeComponent();

            this.SetStyle(
                        ControlStyles.UserPaint |
                        ControlStyles.AllPaintingInWmPaint |
                        ControlStyles.OptimizedDoubleBuffer, true);
            this.active = new List<Rectangle>();
            this.spacer = 10;
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            Graphics g = pe.Graphics;

            using (Pen pBlack = new Pen(Color.FromArgb(0, 0, 0), 1))
            {
                pBlack.DashStyle = DashStyle.Dot;
               
                for (int i = 0; i < (int)this.Height / this.spacer; i++)
                    g.DrawLine(pBlack, new Point(0, (i * spacer) + spacer), new Point(this.Width, (i * spacer) + spacer));

                for (int i = 0; i < (int)this.Width / this.spacer; i++)
                    g.DrawLine(pBlack, new Point((i * spacer) + spacer, 0), new Point((i * spacer) + spacer, this.Height));

                pBlack.DashStyle = DashStyle.Solid;
                g.DrawRectangle(pBlack, new Rectangle(new Point(0, 0), new Size(this.Width-1,this.Height-1)));
            }

            using (SolidBrush sbRed = new SolidBrush(Color.Red))
            {
                foreach (Rectangle r in active)
                {
                    g.FillRectangle(sbRed, r);
                }
            }
            base.OnPaint(pe);
        }

        private bool mouseDown;
        private void GridControl_MouseDown(object sender, MouseEventArgs e)
        {
            this.mouseDown = true;
        }

        private void GridControl_MouseMove(object sender, MouseEventArgs e)
        {
            if (mouseDown)
            {
                Rectangle r = new Rectangle();
                r.X = ((e.X / this.spacer) * this.spacer) + 1;
                r.Y = ((e.Y / this.spacer) * this.spacer) + 1;
                r.Size = new Size(spacer - 1, spacer - 1);
                if (!this.active.Contains(r))
                {
                    this.active.Add(r);
                    this.Refresh();
                }
            }
        }

        private void GridControl_MouseUp(object sender, MouseEventArgs e)
        {
            this.mouseDown = false;
        }
    }
}
-------------------------------------------------------------------------------------

GridControl.Designer.cs
-------------------------------------------------------------------------------------
namespace ChrExcample
{
    partial class GridControl
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.SuspendLayout();
            //
            // GridControl
            //
            this.Size = new System.Drawing.Size(100, 100);
            this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.GridControl_MouseDown);
            this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.GridControl_MouseMove);
            this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.GridControl_MouseUp);
            this.ResumeLayout(false);

        }

        #endregion
    }
}
-------------------------------------------------------------------------------------

Ja det var så et forsøg på at få dig til at forstå konceptet i en Control lidt bedre... Det resultere i at du tegner dig ud af din opgave, dvs at du tegner alle linierne i dit grid, du tegener kasserne og rammen og hvad du ellers kunne finde på...

Du kan have billeder som baggrund, eller en specifik bagrundsfarve, linierne og kasserne kan også farves som du lyster... og en hel del mere...
Avatar billede md_craig Nybegynder
06. juli 2006 - 10:54 #10
Hvorfor det du laver ikke virker kan jeg ikke 100% svarer på, ved ikke om det kan have noget at gøre med hvor event'sne er placeret... men kigger lige lidt på det også...

En af de store ulæmper u dit er nok alle de objekter du får i spil, og da det er Controll's fylder lidt... desuden er der pluselig mange flere control's din form skal igennem og tegne... for hver af de pictureboxes du har, skal tegnes med deres egen OnPaint metode, hvor en enkelt Control løsning bliver der kun en control at tegne, ikke 400 stk...

Men enyways... kan godt lige kigge og se om jeg kan finde noget...
Avatar billede md_craig Nybegynder
06. juli 2006 - 11:19 #11
Yeps... tænkte det nok, dit problem ligger i hvor dine Events er...
I det du klikker på en af dine Picture boxe, så låser Move eventet sig til den ene box, dvs det er ALTID den der sender dig move eventet, og ergo får du altid samme placering...
Avatar billede md_craig Nybegynder
06. juli 2006 - 11:25 #12
du kan erstatte din Mousemove med:

        private void mouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            label2.Text = string.Format("mouseMove at: {0},{1}", e.X, e.Y);
          if (drawNow)
          {
                Point location = ((PictureBox)sender).Location;
                int x = (location.X + e.X) / (this.panel1.Width / 20);
                int y = (location.Y + e.Y) / (this.panel1.Height / 20);

                label1.Text = string.Format("mouseMove at: {0},{1}", x, y);

                try
                {
                    pbList[x, y].BackColor = Color.Black;
                }
                catch
                { }
          }
        }
Avatar billede ahara Nybegynder
06. juli 2006 - 11:26 #13
Tak for hjælpen. Kigger på din kode. Hvad ang. min egen kode hvor kunne jeg så placere mine events i stedet for i Form_load
Avatar billede ahara Nybegynder
06. juli 2006 - 11:28 #14
Ok. Kan se du allerede har svaret - sorry. Der er point og jeg kigger nærmere på din kode. Tusind tak
Avatar billede md_craig Nybegynder
06. juli 2006 - 11:53 #15
svar :D
Avatar billede md_craig Nybegynder
06. juli 2006 - 12:31 #16
Lige en NB til min kode, fandt ud af at det du mente med 5 x 5 felter var antal Felter i grid og ikke størelsen på feltet...
Så skal der ændres en smule da jeg fik det kringlet ind i mit hoved på den anden måde...

Dette ændre den så den arbejder på en grid dimention istedet:


GridControl.cs
-------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace ChrExcample
{
    public partial class GridControl : Control
    {
        private Size dimention;
        private List<Rectangle> active;

        public Size Dimention
        {
            get { return dimention; }
            set {    dimention = value; }
        }

        public GridControl()
        {
            InitializeComponent();

            this.SizeChanged += new EventHandler(GridControl_SizeChanged);
            this.dimention = new Size(10, 10);
            this.SetStyle(
                        ControlStyles.UserPaint |
                        ControlStyles.AllPaintingInWmPaint |
                        ControlStyles.OptimizedDoubleBuffer, true);
            this.active = new List<Rectangle>();
        }

        void GridControl_SizeChanged(object sender, EventArgs e)
        {
            this.Height = (this.Height / this.dimention.Height) * this.dimention.Height;
            this.Width = (this.Width / this.dimention.Width) * this.dimention.Width;
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            Graphics g = pe.Graphics;

            using (Pen pBlack = new Pen(Color.Black, 1))
            {
                pBlack.DashStyle = DashStyle.Dot;
               
                int ySpace = this.Height / this.dimention.Height;
                for (int i = 0; i < this.dimention.Height; i++)
                    g.DrawLine(pBlack, new Point(0, (i * ySpace) + ySpace), new Point(this.Width, (i * ySpace) + ySpace));

                int xSpace = this.Width / this.dimention.Width;
                for (int i = 0; i < this.dimention.Width; i++)
                    g.DrawLine(pBlack, new Point((i * xSpace) + xSpace, 0), new Point((i * xSpace) + xSpace, this.Height));

                pBlack.DashStyle = DashStyle.Solid;
                g.DrawRectangle(pBlack, new Rectangle(new Point(0, 0), new Size(this.Width-1,this.Height-1)));
            }

            using (SolidBrush sbRed = new SolidBrush(Color.Red))
            {
                foreach (Rectangle r in active)
                {
                    g.FillRectangle(sbRed, r);
                }
            }
            base.OnPaint(pe);
        }

        private bool mouseDown;
        private void GridControl_MouseDown(object sender, MouseEventArgs e)
        {
            this.mouseDown = true;
        }

        private void GridControl_MouseMove(object sender, MouseEventArgs e)
        {
            if (mouseDown)
            {
                int xSpace = this.Width / this.dimention.Width;
                int ySpace = this.Height / this.dimention.Height;

                Rectangle r = new Rectangle();
                r.X = ((e.X / xSpace) * xSpace) + 1;
                r.Y = ((e.Y / ySpace) * ySpace) + 1;
                r.Size = new Size(xSpace - 1, ySpace - 1);
                if (!this.active.Contains(r))
                {
                    this.active.Add(r);
                    this.Refresh();
                }
            }
        }

        private void GridControl_MouseUp(object sender, MouseEventArgs e)
        {
            this.mouseDown = false;
        }
    }
}
-------------------------------------------------------------------------------------

GridControl.Designer.cs
-------------------------------------------------------------------------------------
namespace ChrExcample
{
    partial class GridControl
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.SuspendLayout();
            //
            // GridControl
            //
            this.Size = new System.Drawing.Size(100, 100);
            this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.GridControl_MouseDown);
            this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.GridControl_MouseMove);
            this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.GridControl_MouseUp);
            this.ResumeLayout(false);

        }

        #endregion
    }
}
-------------------------------------------------------------------------------------
Avatar billede ahara Nybegynder
06. juli 2006 - 13:44 #17
Perfekt. Tak for god service :0)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester