WinForm rysowanie kontrolki

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);
        }
    }
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/questions/7507602/best-practice-for-onpaint-invalidate-clipping-and-regions

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

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

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);
                }
            }
        }
    }
}
0
datGuy napisał(a):

Obrazek jest tylko prostym przykładem.

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

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