Я делаю настраиваемый элемент управления (унаследованный от VisualBasic.PowerPacks.LineShape
), который должен быть нарисован как стандартный, но рядом с ним должен отображаться значок.
Итак, я просто переопределил OnPaint
вот так:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
e.Graphics.DrawIcon(myIcon, StartPoint.X, StartPoint.Y);
base.OnPaint(e);
}
Сейчас все в порядке, но когда мой контроль перемещается, значок все еще остается нарисованным на древнем месте.
Есть ли способ правильно его покрасить?
http://lh4.ggpht.com/_1TPOP7DzY1E/S5gXmp7xYiI/AAAAAAAADHI/pa1OhpKYSoM/Untitled-2.png Реальная ситуация с проектом
КОД: пример кода для тестов.
http://lh6.ggpht.com/_1TPOP7DzY1E/S5jSluxvtDI/AAAAAAAADHw/EUz0Tfet-rw/s800/Capture2.png
using Microsoft.VisualBasic.PowerPacks;
using System.Windows.Forms;
using System.Drawing;
namespace LineShapeTest
{
///
/// Test Form
///
public class Form1 : Form
{
IconLineShape myLine = new IconLineShape();
ShapeContainer shapeContainer1 = new ShapeContainer();
Panel panel1 = new Panel();
public Form1()
{
this.panel1.Dock = DockStyle.Fill;
// load your back image here
this.panel1.BackgroundImage =
global::WindowsApplication22.Properties.Resources._13820t;
this.panel1.Controls.Add(shapeContainer1);
this.myLine.StartPoint = new Point(20, 30);
this.myLine.EndPoint = new Point(80, 120);
this.myLine.Parent = this.shapeContainer1;
MouseEventHandler panelMouseMove =
new MouseEventHandler(this.panel1_MouseMove);
this.panel1.MouseMove += panelMouseMove;
this.shapeContainer1.MouseMove += panelMouseMove;
this.Controls.Add(panel1);
}
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
myLine.StartPoint = e.Location;
}
}
}
///
/// Test LineShape
///
public class IconLineShape : LineShape
{
Icon myIcon = SystemIcons.Exclamation;
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
e.Graphics.DrawIcon(myIcon, StartPoint.X, StartPoint.Y);
base.OnPaint(e);
}
}
}
Nota Bene для lineShape:
Parent = ShapeContainer
Parent.Parent = Panel
Обновление 1 TRACES
В этом варианте OnPaint у нас есть трассировки:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
Graphics g = Parent.Parent.CreateGraphics();
g.DrawIcon(myIcon, StartPoint.X, StartPoint.Y);
base.OnPaint(e);
}
http://lh4.ggpht.com/_1TPOP7DzY1E/S5j29lutQ0I/AAAAAAAADH4/4yEnZd_hPjA/s800/Capture3.png
Обновить 2 Мигает
В этом варианте OnPaint у нас есть мигающее изображение:
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
Parent.Parent.Invalidate(this.Region, true);
Graphics g = Parent.Parent.CreateGraphics();
g.DrawIcon(myIcon, StartPoint.X, StartPoint.Y);
base.OnPaint(e);
}
http://lh5.ggpht.com/_1TPOP7DzY1E/S5j4Bam7hiI/AAAAAAAADIA/1hQWKyV8Fr0/s800/Capture4.png
Обновление 3: внешняя недействительность
Этот вариант работает хорошо, но ... снаружи класса IconLineShape:
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Region r = myLine.Region;
myLine.StartPoint = e.Location;
panel1.Invalidate(r);
}
}
///
/// Test LineShape
///
public class IconLineShape : LineShape
{
Icon myIcon = SystemIcons.Exclamation;
Graphics parentGraphics;
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
parentGraphics.DrawIcon(myIcon, StartPoint.X, StartPoint.Y);
base.OnPaint(e);
}
protected override void OnParentChanged(System.EventArgs e)
{
// Parent is a ShapeContainer
// Parent.Parent is a Panel
parentGraphics = Parent.Parent.CreateGraphics();
base.OnParentChanged(e);
}
}
Даже это решает проблему тестового примера, мне нужно, чтобы этот элемент управления выполнялся внутри элемента управления, потому что я не могу заставить внешних «клиентов» этого элемента управления не забывать сохранять старую область и аннулировать родительский элемент каждый раз при изменении местоположение...
LabelWithIcon : Label
. Я унаследовал LineShape (компонент). - person serhio   schedule 11.03.2010