WinForm rysowanie kontrolki

Odpowiedz Nowy wątek
2016-09-28 15:43

Rejestracja: 3 lata temu

Ostatnio: 3 lata temu

0

Cześć,

Załóżmy, że rysuję obrazek składający się z 2 części:

  1. ramka,
  2. obraz wewnątrz ramki.

Czy istnieje sposób, na niezależne kontrolowanie obu elementów, to znaczy, żeby np. zmiana koloru ramki nie wymuszała konieczności rysowania całej kontrolki na nowo, tylko samej ramki?

public partial class Obraz : UserControl
    {
        Point[] punktyRamki;

        public Obraz()
        {
            InitializeComponent();

            punktyRamki = new Point[5];
            punktyRamki[0] = new Point(0, 0);
            punktyRamki[1] = new Point(0, this.Width);
            punktyRamki[2] = new Point(this.Width, this.Height);
            punktyRamki[3] = new Point(this.Height, 0);
            punktyRamki[4] = new Point(0, 0);
        }

        #region KOLOR RAMY

        private Color kolorRamy = Color.Brown;

        [System.ComponentModel.Browsable(true),
            System.ComponentModel.Category("Obraz"),
            Description("KolorRamy")]
        public Color KolorRamy
        {
            get
            {
                return kolorRamy;
            }
            set
            {
                kolorRamy = value;
                Invalidate();
            }
        }

        #endregion

        #region KOLOR WYPEŁNIENIA

        private Color kolorWypelnienia = Color.Red;

        [System.ComponentModel.Browsable(true),
            System.ComponentModel.Category("Obraz"),
            Description("KolorWypelnienia")]
        public Color KolorWypelnienia
        {
            get
            {
                return kolorWypelnienia;
            }
            set
            {
                kolorWypelnienia = value;
                Invalidate();
            }
        }

        #endregion

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            this.BackColor = kolorWypelnienia;

            Pen pen = new Pen(kolorRamy, 20);
            e.Graphics.DrawLines(pen, punktyRamki);
        }
    }

Pozostało 580 znaków

2016-09-28 16:21

Rejestracja: 16 lat temu

Ostatnio: 17 godzin temu

0

Jedyne, co mi na szybko przychodzi do głowy to InvalidateRect (musisz sobie to chyba sam zaimportować z WinApi) lub Invalidate z parametrem Rectangle i odmalowujesz 4 recty - 4 fragmenty ramki. Ale wydaje mi się, że to nie jest poprawna droga.
Może Ci jeszcze pomoże coś stąd: http://stackoverflow.com/ques[...]validate-clipping-and-regions

Pozostało 580 znaków

2016-09-28 18:04

Rejestracja: 7 lat temu

Ostatnio: 8 godzin temu

0

trzymaj raz namalowany obraz wewnątrz ramki w buforze (dodatkowa bitmapa) i w OnPaint rysuj ramkę i obraz z bufora. Bufor uaktualniaj tylko wtedy kiedy się obraz zmieni


Chcesz pomocy - pokaż kod - abrakadabra źle działa z techniką.

Pozostało 580 znaków

2016-09-28 21:36

Rejestracja: 3 lata temu

Ostatnio: 3 lata temu

0

Obrazek jest tylko prostym przykładem. Wykorzystanie bufora nie rozwiązuje problemu :(
To by musiało być coś w stylu dwóch różnych kontrolek, niestety nie mam w tym doświadczenia i nie wiem jak się coś takiego robi. Z tego co widzę, temat jest bardziej skomplikowany niż myślałem. :D

Pozostało 580 znaków

2016-09-28 22:34

Rejestracja: 16 lat temu

Ostatnio: 15 godzin temu

1

Pisane na szybko, więc miejscami kod brzydki.

using System;
using System.Drawing;
using System.Windows.Forms;

namespace datguy
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            obraz1.FrameColor = Color.AliceBlue;
        }
    }

    public class Obraz : UserControl
    {
        int borderSize = 10;
        Color _FrameColor = Color.Brown;

        public Color FrameColor
        {
            get
            {
                return _FrameColor;
            }
            set
            {
                _FrameColor = value;
                InvalidateFrame();
            }
        }

        void GetFrameRects(out Rectangle rtop, out Rectangle rleft, out Rectangle rright, out Rectangle rbottom, out Rectangle rmiddle)
        {
            rtop = new Rectangle(0, 0, Width, borderSize);
            rbottom = new Rectangle(0, Height-borderSize, Width, borderSize);
            rleft = new Rectangle(0, borderSize, borderSize, Height-borderSize-borderSize);
            rright = new Rectangle(Width-borderSize, borderSize, borderSize, Height-borderSize-borderSize);
            rmiddle = new Rectangle(borderSize, borderSize, Width - borderSize - borderSize, Height - borderSize - borderSize);
        }

        void InvalidateFrame()
        {
            Rectangle rtop, rbottom, rleft, rright, rmiddle;
            GetFrameRects(out rtop, out rbottom, out rleft, out rright, out rmiddle);
            // te update'y są tu konieczne jeśli chcemy uniknąć odrysowania wnętrza
            Invalidate(rtop);
            Update();
            Invalidate(rleft);
            Update();
            Invalidate(rright);
            Update();
            Invalidate(rbottom);
            Update();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            using (Brush brusz = new SolidBrush(FrameColor))
            {
                Rectangle rtop, rbottom, rleft, rright, rmiddle;
                GetFrameRects(out rtop, out rbottom, out rleft, out rright, out rmiddle);

                var rect = e.ClipRectangle;

                if (rect.IntersectsWith(rtop))
                {
                    // rysuj górną ramkę dowolnym sposobem
                    e.Graphics.FillRectangle(brusz, rtop);
                }
                if (rect.IntersectsWith(rleft))
                {
                    // lewą ramkę
                    e.Graphics.FillRectangle(brusz, rleft);
                }
                if (rect.IntersectsWith(rright))
                {
                    //  prawą ramkę
                    e.Graphics.FillRectangle(brusz, rright);
                }
                if (rect.IntersectsWith(rbottom))
                {
                    // dolną ramkę
                    e.Graphics.FillRectangle(brusz, rbottom);
                }
                if (rect.IntersectsWith(rmiddle))
                {
                    // wnętrze
                    e.Graphics.FillRectangle(Brushes.Navy, rmiddle);
                }
            }
        }
    }
}

Pozostało 580 znaków

2016-09-28 22:46

Rejestracja: 7 lat temu

Ostatnio: 8 godzin temu

0
datGuy napisał(a):

Obrazek jest tylko prostym przykładem.

to czego oczekujesz nie pisząc co tak na prawdę chcesz zrobić?


Chcesz pomocy - pokaż kod - abrakadabra źle działa z techniką.

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0