C# - Pomalé vykreslování? Vyřešeno

Místo pro dotazy a rady ohledně programovacích jazyků (C++, C#, PHP, ASP, Javascript, VBS..) a tvorby webových stránek

Moderátor: Mods_senior

Rutherther
Level 2
Level 2
Příspěvky: 227
Registrován: říjen 14
Pohlaví: Muž
Stav:
Offline

C# - Pomalé vykreslování?  Vyřešeno

Příspěvekod Rutherther » 15 lis 2015 15:23

Zdravím, mám takový problém, dělám aplikaci do školy a chtěl jsem si vše v ní nakreslit buď ve WF na PictureBox nebo ve WPF na Image.

Vyskytly se mi ale komplikace a potřebuji pomoc, vždy se mi to vykreslí za delší čas, třeba více jak 2 s, zkoušel jsem se přes debug podívat na to, kde to bere tolik času, ale docela bez úspěchu, protože nejsem v debugu zase takový znalec, nepohcopil jsem, proč mi to ukazovalo třeba na ukončené složené závorce 210 ms, takže jsem se nehnul z místa. Zkoušel jsem to už dost předělat, nejdříve jsem to měl na WPF, teď ve WF (s WPF nemám moc zkušeností a tak jsem to zkusil takto vyřešit, neúspěšně). Zkoušel jsem to udělat i přes eventy, ale nechápu, co jsem si od toho sliboval. :D

Kód mám rozdělen do několika tříd a jednoho rozhraní, všechno zde pošlu.

Omlouvám se, že jsou někde nějaké věci navíc (nepoužity), např. Dispatcher ve tříde MainTask, kde není vůbec použit, je to z důvodu, že jsem nejdříve PictureBoxu přiřazoval obrázek přes něj.

Kód: Vybrat vše

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PercentagesPractise.ScreenObjects
{
    interface IScreenObject
    {
        bool isActive();
        void Draw(Graphics g);
        void _Update();
    }
}


Kód: Vybrat vše

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PercentagesPractise.ScreenObjects
{
    class ScreenObject : IScreenObject
    {
        //Click, Hover ...
        public EventHandler OnClick { get; set; }
        public EventHandler OnDoubleClick { get; set; }
        public EventHandler OnHover { get; set; }
        //Update
        public EventHandler BeforeUpdate { get; set; }
        public EventHandler Update { get; set; }
        public EventHandler AfterUpdate { get; set; }

        public bool isActivated { get; set; }

        public bool isActive()
        {
            return isActivated;
        }
        public bool Fill
        {
            get
            {
                return fill;
            }
            set
            {
                fill = value;
            }
        }

        public Color color;
        public Rectangle rectangle;
        public float width;
        public bool fill;

        public ScreenObject(Color color, Rectangle rectangle, bool fill = false, float width = 1)
        {
            BeforeUpdate += (sender, e) => { };
            Update += (sender, e) => { };
            AfterUpdate += (sender, e) => { };
            isActivated = true;
            this.color = color;
            this.rectangle = rectangle;
            this.width = width;
            this.fill = fill;
        }



        public virtual void _Update()
        {
            BeforeUpdate(null, null);
            Update(null, null);
            AfterUpdate(null, null);
        }

        public virtual void Draw(Graphics g)
        {

            if (fill)
                g.FillRectangle(new SolidBrush(color), rectangle.x, rectangle.y, rectangle.width, rectangle.height);
            else
            {
                Pen p = new Pen(color, width);
                g.DrawRectangle(p, rectangle.x, rectangle.y, rectangle.width, rectangle.height);
            }
        }
    }
}


Kód: Vybrat vše

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PercentagesPractise.ScreenObjects
{
    class Screen : IScreenObject
    {
        protected List<ScreenObject> objs { get; set; }
        public bool isActivated { get; set; }
        public Screen(List<ScreenObject> objs)
        {
            this.objs = objs;
            isActivated = true;
        }
        public bool isActive()
        {
            return isActivated;
        }
        public void Draw(Graphics g)
        {
           foreach(ScreenObject obj in objs)
            {
                obj.Draw(g);
            }
        }
        public void _Update()
        {
            foreach (ScreenObject obj in objs)
            {
                obj._Update();
            }
        }
    }
}


Kód: Vybrat vše

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using System.Windows.Threading;

namespace PercentagesPractise.ScreenObjects
{
    class MainTask
    {
        public EventHandler<Bitmap> onDraw { get; set; }
        List<IScreenObject> activeObjects
        {
            get
            {
                List <IScreenObject> objs = new List<IScreenObject>(objects);
                if(objects != null)
                foreach(IScreenObject obj in objects)
                {
                    if (!obj.isActive())
                        objs.Remove(obj);
                }
                return objs;
            }
        }
        public bool IsRunning {
            get
            {
                return running;
            }
            set
            {
                if (value && !running)
                    Start();
                running = value;
            }
        }

        public int Width
        {
            get
            {
                return width;
            }
            set
            {
                width = value;
            }
        }

        public int Height
        {
            get
            {
                return height;
            }
            set
            {
                height = value;
            }
        }

        private List<IScreenObject> objects = new List<IScreenObject>();
        private Thread updater, drawer;
        private Dispatcher dis;
        private bool running;
        private int width, height;
        private System.Windows.Forms.PictureBox pb;
        public MainTask(List<IScreenObject> objs, Dispatcher dis, System.Windows.Forms.PictureBox pb)
        {
           // onDraw += (sender, e) => { };
            this.dis = dis;
            if(objs != null)
              objects = objs;
            this.pb = pb;
        }

        public void Start()
        {
            running = true;

            Bitmap b = new Bitmap(1920, 1024);
           // onDraw(null, b);
            Graphics g = Graphics.FromImage(b);
            drawer = new Thread(new ThreadStart(() => {

                while (running)
                {
                   // if (onDraw == null)
                   //     continue;

                    g.FillRectangle(Brushes.Gray, 0, 0, 1920, 1024);
                    foreach (IScreenObject obj in objects)
                    {
                        obj.Draw(g);
                    }
                    pb.Image = new Bitmap(b, new System.Drawing.Size(width, height));
                    //onDraw(null, );
                }
            }));
            updater = new Thread(new ThreadStart(() =>
            {
                while (running)
                {
                    foreach (IScreenObject obj in activeObjects)
                    {
                        obj._Update();
                    }
                }
            }));
            updater.Start();
            drawer.Start();
           

        }
        public void Clicked(PointF pos)
        {
            MessageBox.Show("CLICKED! " + pos.X + " " + pos.Y);
        }

    }
}


Kód: Vybrat vše

using PercentagesPractise.ScreenObjects;
using PercentagesPractise.ScreenObjects.AddonFunctions;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PercentagesPractise.Screens
{
    class MainScreen : Screen
    {
        public MainScreen() : base(null)
        {
            List<ScreenObject> objs = new List<ScreenObject>();

            //Background
            ScreenObjects.Rectangle bcg = new ScreenObjects.Rectangle(0, 0, 1920, 1080);
            ScreenObject bcgso = new ScreenObject(Color.Black, bcg, true);
            //objs.Add(bcgso);


            ScreenObjects.Rectangle rct = new ScreenObjects.Rectangle(500, 500, 20, 20);
            ScreenObject obj = new ScreenObject(Color.Blue, rct, true);
            Random r = new Random();
            Vector v = new Vector(20f, 20f);
            obj.Update += (sender, e) => {

                if (obj.rectangle.x < 0 || obj.rectangle.x > 1920)
                    v.x = -v.x;
                if (obj.rectangle.y < 0 || obj.rectangle.y > 1024)
                    v.y = -v.y;

                obj.rectangle.x += v.x;
                obj.rectangle.y += v.y;
            };
            bcgso.isActivated = false;
            objs.Add(obj);


            this.objs = objs;
        }
    }
}


Kód: Vybrat vše

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PercentagesPractise.ScreenObjects.AddonFunctions
{
    class Vector
    {


        public float x { get; set; }
        public float y { get; set; }

        public Vector(float xy)
        {
            x = y = xy;
        }
        public Vector(float x, float y)
        {
            this.x = x;
            this.y = y;
        }
        public Vector()
        {

        }

        public void Reverse()
        {
            x = -x;
            y = -y;
        }

    }
}


Kód: Vybrat vše

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PercentagesPractise.ScreenObjects
{
    struct Rectangle
    {
        public float x, y;
        public float width, height;

        public Rectangle(float x, float y, float width, float height)
        {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
        }
    }
}



Tohle mám ve třídě WP.

Kód: Vybrat vše

        private void app_Load(object sender, EventArgs e)
        {
            List<IScreenObject> se = new List<IScreenObject>();
            ScreenObjects.Screen scr = new MainScreen();
            se.Add(scr);
            MainTask t = new MainTask(se, Dispatcher.CurrentDispatcher, image);
            t.Width = image.Width;
            t.Height = image.Height;
            t.Start();
        }


Děkuji všem, kteří se alespoň na kód podívají.

Reklama
Uživatelský avatar
CZechBoY
Master Level 9.5
Master Level 9.5
Příspěvky: 8813
Registrován: srpen 08
Bydliště: Brno
Pohlaví: Muž
Stav:
Offline
Kontakt:

Re: C# - Pomalé vykreslování?

Příspěvekod CZechBoY » 16 lis 2015 11:21

Problém asi bude, že to kreslíš do nějaký bitmapy nebo čeho a to až potom vykresluješ. Kresli to přímo do toho PictureBoxu nebo Panelu.

Kód: Vybrat vše

MyPictureBox.onPaint += new System.EventHandler(this.MyPictureBoxOnPaint);

private void MyPictureBoxOnPaint (object sender, PaintEventArgs e)
{
    e.Graphics.DrawLine(...);
}
PHP, Nette, MySQL, C#, TypeScript, Python
IntelliJ Idea, Docker, Opera browser, Linux Mint
iPhone XS
Raspberry PI 3 (KODI, Raspbian)
XBox One S, PS 4, nVidia GeForce NOW

Rutherther
Level 2
Level 2
Příspěvky: 227
Registrován: říjen 14
Pohlaví: Muž
Stav:
Offline

Re: C# - Pomalé vykreslování?

Příspěvekod Rutherther » 16 lis 2015 16:45

CZechBoY píše:Problém asi bude, že to kreslíš do nějaký bitmapy nebo čeho a to až potom vykresluješ. Kresli to přímo do toho PictureBoxu nebo Panelu.


Díky, tohle mi pomohlo, bylo to tím, udělal jsem to ale jinak: pictureBox.CreateGraphics().

CZechBoY píše:

Kód: Vybrat vše

MyPictureBox.onPaint += new System.EventHandler(this.MyPictureBoxOnPaint);

private void MyPictureBoxOnPaint (object sender, PaintEventArgs e)
{
    e.Graphics.DrawLine(...);
}


Tohle nefunguje, jde o to, že PictureBox nemá tento EventHandler, má možná tak Paint, ale to se volá jen třeba při otevření okna, přesunutí okna atd.

Teď mám problém s tím, že to problikává :D pokusím se to nějak vyřešit

Dodatečně přidáno po 38 minutách 28 vteřinách:
Tak jsi měl pravdu, jen jsi mohl napsat něco o pictureBox.Invalidate();
Ta moje verze prostě problikává a problikávat bude :D
Ještě jednou díky


  • Mohlo by vás zajímat
    Odpovědi
    Zobrazení
    Poslední příspěvek
  • Pomalé načítaní Win 11 pro Příloha(y)
    od PARKR » 07 úno 2025 19:22 » v Windows 11, 10, 8...
    4
    2473
    od PARKR Zobrazit poslední příspěvek
    08 úno 2025 09:18
  • Pomalé, žádné nabíjení telefonu Příloha(y)
    od muffin105 » 23 lis 2024 21:37 » v Mobily, tablety a jiná přenosná zařízení
    9
    3600
    od muffin105 Zobrazit poslední příspěvek
    24 lis 2024 14:41

Zpět na “Programování a tvorba webu”

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 2 hosti