 |
|
|
 |
|
 |
can i do the same in panel?????? i have panel in my project instead of picturebox
|
|
|
|
 |
|
 |
I think so, you have to get the graphic context of the panel control, using something like this:
Graphics g = panel.CreateGraphics();
Sam:"Better to reign in hell, than to serve in heaven", John Milton.
Max:"Heaven is a place were nothing ever happens", David Byrne.
|
|
|
|
 |
|
|
 |
|
|
 |
|
 |
You have said in the article as below : -
but they simply are a red square (that can be personalized, a cross, a circle, etc,), with no code inside.
I am new to C#. Could you please let me know the exact steps to do this. I want to replace the square with cross.
|
|
|
|
 |
|
 |
Hi! You only have to change the appearance of the MarkControl User Control. Use a red cross image for background or something like that...
Sam:"Better to reign in hell, than to serve in heaven", John Milton.
Max:"Heaven is a place were nothing ever happens", David Byrne.
|
|
|
|
 |
|
 |
I've been trying to do exactly this on and off for months.
No Flicker!!!
Even has grab handles.
Now I know it can be done, and done well.
Thank You very Much
|
|
|
|
 |
|
|
 |
|
 |
I have found great help from your article. In 'MarkControl' I need to dispaly some text under image, I place a 'Label' control and set it's value when control initilize (In constructor). It's working fine, but when characters increases I need to Wrap the Text. Because as number of charters increase it display it in single line. I'm unable to do Text wraping in label control.
Please help to figure out this problem.
Riz
|
|
|
|
 |
|
 |
Hi, I'm very happy that you've find useful my "3-years-old" article
However, if you have the need to place a label, you can draw it, instead of placing a label control. Using the Graphics.DrawString(...), you can write text directly to the background, then rewriting it while moving the marker or at the end of it's movement (in the mouseup event) for better performances.
In this way, you can draw the text as you wish.
Bye!
Sam:"Better to reign in hell, than to serve in heaven", Milton.
Max:"Heaven is a place were nothing ever happens", David Byrne.
|
|
|
|
 |
|
 |
Hi, I changed the PictureBoxSizemode from Normal to Zoom because I want to load a big images, but when I load my image and then I add some lines, the marks are not on the beggining and end of the line but the line is in the correct position/pixels.
Do you know how to move the marks to the correct position before add them??
I think you need to calculate the zoom ratio that the picturebox makes to the image and then recalculate the position of the marks respect the image and the line, but I don't know how to make it.
Can you help me please?
You can see it changing the sizemode to the picturebox and loading a big image and adding some lines.
Thanks
|
|
|
|
 |
|
 |
Hi!
I think you have to do a 2D geometric transformation, trasform any single point (mark.center) and then redraw lines...
Uhm... but you've just said that lines draw themselves in the correct way, then, there is something that I don't understand... Lines just draw from marker-to-marker... Give me an hint
Sam:"Better to reign in hell, than to serve in heaven", Milton.
Max:"Heaven is a place were nothing ever happens", David Byrne.
|
|
|
|
 |
|
 |
Hi, If you give me your mail I'll send you various screenshots about the problem.
Also you can see the problem first changing the property 'sizemode' of the picturebox to 'Zoom' and after loading a big Image or photo, and finally adding some lines to the image.
Give me your mail please.
my mail is: jmpxupi@gmail.com
thanks
|
|
|
|
 |
|
 |
Now I have two more problems.
I) Redraw() function works very fast when the pictureBox.Size = (747, 486) as I will increase the size of pictureBox like in my program pictureBox.Size = (1500, 1500). Redraw() function will take some more time while drawing lines?
II) I want to add a functionality in my program that when user want to see the relations between Entities and calculation points reached the top bound or left bound of PictureBox area it should automatically increase the pictureBox size.
I used System.Windows.Forms.Panel control for achieving scrolling in my project, but as I increase the size of pictureBox when drawing points reached to the limitation of pictureBox it increase the size from bottom or right while I want it should increase from top and left.
Thanks in advance
Riz
|
|
|
|
 |
|
 |
Your article is great. I have found great help out of it. But the technique u used becomes slower when number of record increases.
Actually I'm developing an application where user can see the associated relations and move the entities on MouseMove. Relationships have of two types I) 1 to 1 relationship
II) 1 to many relationship
1 to 1 shown with Line, while 1 to many shown with Curve. Text should be displayed using MidPoint formula wit the help of Graphics.TranslateTransform() function.
Problem occurs when number of relationships exceed from 50.Redrawing does not work smoothly. Please let me know if u have any other idea to make it more faster on MouseMove.
Thanks in advance
Riz
|
|
|
|
 |
|
 |
Ahrr, the usual problem ;D Performances!
Right, I'll try to give you some advice
1) Don't use "redraw all" thing while MouseMove event. Try to do it in the overrided OnPaint of the paintbox, setting a timer (this way you can set the redrawing frequency, hopefully increasing performances) or/and try to improve the GetRegionByLine to invalidate a smaller area...
2) GDI+ sucks, let me say it... If you can, try newest technologies, DirectX, opengl, etc...
3) There is a open source project, a photoshop-like application called Paint.Net, you can download both source and app... I hadn't seen the source code yet, but maybe you would find something useful...
Thank ya and bye! ;D
Sam:"Better to reign in hell, than to serve in heaven", Milton.
Max:"Heaven is a place were nothing ever happens", David Byrne.
|
|
|
|
 |
|
 |
Thanks for suggestions.
Now I have two more problems.
I) Redraw() function works very fast when the pictureBox.Size = (747, 486) as I will increase the size of pictureBox like in my program pictureBox.Size = (1500, 1500). Redraw() function will take some more time while drawing lines?
II) I want to add a functionality in my program that when user want to see the relations between Entities and calculation points reached the top bound or left bound of PictureBox area it should automatically increase the pictureBox size.
I used System.Windows.Forms.Panel control for achieving scrolling in my project, but as I increase the size of pictureBox when drawing points reached to the limitation of pictureBox it increase the size from bottom or right while I want it should increase from top and left.
Thanks in advance
Riz
|
|
|
|
 |
|
 |
Hello,Mr.Dbutch
I repair your code,now I can draw a line and code below.now,how to change line's color when mouse move to line above ,and how to open a form when mouse click line.Thank you very mouch .
code:
/*
* *******************************
* Line Editor by Marco Bellini *
* *
* Please send me feedbacks! : *
* Dbutch.er@tin.it *
* *
* ...and share Knowledge! *
* *
* *******************************
*/
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
namespace LineEditor
{
public class Form1 : System.Windows.Forms.Form
{
private IContainer components;
private System.Windows.Forms.PictureBox image;
private System.Windows.Forms.Button button1;
Bitmap bmpBack = null;
private bool isSelected = false;
private int _X, _Y;
private ArrayList Lines = null;
private struct Line
{
public MarkControl mark1;
public MarkControl mark2;
public int Width;
}
public Form1()
{
InitializeComponent();
Lines = new ArrayList();
bmpBack = new Bitmap(image.Width, image.Height);
Graphics.FromImage(bmpBack).Clear(Color.White);
image.Image = (Bitmap)bmpBack.Clone();
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.image = new System.Windows.Forms.PictureBox();
this.button1 = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.image)).BeginInit();
this.SuspendLayout();
//
// image
//
this.image.BackColor = System.Drawing.SystemColors.ActiveCaptionText;
this.image.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.image.Location = new System.Drawing.Point(19, 17);
this.image.Name = "image";
this.image.Size = new System.Drawing.Size(480, 431);
this.image.TabIndex = 3;
this.image.TabStop = false;
// button1
//
this.button1.Location = new System.Drawing.Point(509, 17);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(134, 43);
this.button1.TabIndex = 11;
this.button1.Text = "Draw Line";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.AutoScroll = true;
this.BackColor = System.Drawing.SystemColors.Control;
this.ClientSize = new System.Drawing.Size(657, 242);
this.Controls.Add(this.button1);
this.Controls.Add(this.image);
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Line Editor";
((System.ComponentModel.ISupportInitialize)(this.image)).EndInit();
this.ResumeLayout(false);
}
#endregion
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void button1_Click(object sender, System.EventArgs e)
{
try
{
//Adds red marks that are the beginning/end of the line
MarkControl mark1 = new MarkControl();
mark1.Location = new Point(50, 50);
image.Controls.Add(mark1);
MarkControl mark2 = new MarkControl();
mark2.Location = new Point(100, 100);
image.Controls.Add(mark2);
//Line Struct contains the information for a single line
Line line = new Line();
line.mark1 = mark1;
line.mark2 = mark2;
line.Width = 1;
//Events for moving marks
mark1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Mark_MouseUp);
mark1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Mark_MouseDown);
mark1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Mark_MouseMove);
mark2.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Mark_MouseUp);
mark2.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Mark_MouseDown);
mark2.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Mark_MouseMove);
//Adds Line object to an arraylist
Lines.Add(line);
Redraw();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//Simply draws a line
private void DrawLine(Line line)
{
Graphics g = null;
g = Graphics.FromImage(image.Image);
g.DrawLine(new Pen(Color.Black, (float)line.Width), line.mark1.Center.X, line.mark1.Center.Y, line.mark2.Center.X, line.mark2.Center.Y);
g.Dispose();
}
//Redraws all the lines and a part of the background
private void Redraw(Line line, Point p)
{
Graphics.FromImage(image.Image).DrawImage(bmpBack, 0, 0, image.Image.Width,
image.Image.Height);
foreach (Line l in Lines)
{
DrawLine(l);
}
image.Update();
}
//Redraws all the lines and the background too
private void Redraw()
{
if (bmpBack != null)
image.Image = (Bitmap)bmpBack.Clone();
else
{
image.Image = new Bitmap(image.Width, image.Height);
Graphics.FromImage(image.Image).Clear(Color.Transparent);
}
foreach (Line l in Lines)
{
DrawLine(l);
}
image.Refresh();
}
private void Mark_MouseDown(object sender, MouseEventArgs e)
{
this.SuspendLayout();
isSelected = true;
_X = e.X;
_Y = e.Y;
}
private void Mark_MouseMove(object sender, MouseEventArgs e)
{
if (isSelected)
{
MarkControl mc1 = (MarkControl)sender;
Line l = getLineByMark(mc1);
Point p = new Point(e.X - _X + mc1.Left, e.Y - _Y + mc1.Top);
mc1.Location = p;
Redraw(l, p);
}
}
private void Mark_MouseUp(object sender, MouseEventArgs e)
{
isSelected = false;
ResumeLayout();
Redraw();
}
//Retrieves a mark having the other one
private MarkControl getOtherMark(MarkControl m)
{
foreach (Line l in Lines)
{
if (l.mark1 == m)
return l.mark2;
if (l.mark2 == m)
return l.mark1;
}//Never happens
throw new Exception("No relative mark found");
}
//Retrieves a Line object having a mark
private Line getLineByMark(MarkControl m)
{
foreach (Line l in Lines)
{
if (l.mark1 == m || l.mark2 == m)
return l;
}//Never happens
throw new Exception("No line found");
}
public class MarkControl : UserControl
{
private Container components = null;
public MarkControl()
{
InitializeComponent();
this.BackColor = Color.Red;
}
public Point Center
{
get { return new Point(Location.X + 4, Location.Y + 4); }
}
protected override void OnPaint(PaintEventArgs e)
{
//
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
#region Component Designer generated code
private void InitializeComponent()
{
this.SuspendLayout();
//
// MarkControl
//
this.Name = "MarkControl";
this.Size = new System.Drawing.Size(9, 9);
this.ResumeLayout(false);
}
#endregion
}
}
}
My email:junzhi_li@hotmail.com & remi_lijunzhi@yahoo.com.cn
evryone can solve it ,thank you very much!!
strong man,Aha.
|
|
|
|
 |
|
 |
The first additional function I would like to add to this project is a resizable graphic area to match the Form window size.
So I changed the anchor property of button1 to Top, Right and the anchor property of image to Top,Bottom,Left,Right.
Then I added the resize event:
void ImageResize (object sender , System.EventArgs e)
{
bmpBack = new Bitmap (image.Width , image.Height)
}
These changes introduced 2 new problems.
1 - now you see rubber banding whenever you drag a line end marker
2 - the ImageResize needs additional code to proportionally scale up or down the existing lines (as occurs with current commercial graphic software applications)
Any ideas on how to solve these problems?
|
|
|
|
 |
|
|
 |
|
 |
I started this way...
void ImageResize(object sender, System.EventArgs e)
{
double Scale1 = image.Width / bmpBack.Width;
int LCount = Lines.Count;
for (int i = 0 ; i < LCount ; i++)
{
Line l = (Line)Lines[i];
MarkControl mc1 = l.mark1;
MarkControl mc2 = l.mark2;
Point p1 = new Point(Convert.ToInt16(mc1.Location.X * Scale1) ,
Convert.ToInt16(mc1.Location.Y * Scale1));
mc1.Location = p1;
Point p2 = new Point(Convert.ToInt16(mc2.Location.X * Scale1) ,
Convert.ToInt16(mc2.Location.Y * Scale1));
mc2.Location = p2;
but then hit 2 problems...
that scaling factor isnt quite right and
I havent figured out how to update the lines. All attempts so-far have had horrible results.
mmmm... I suppose this is far from the anchor idea you just mentioned... sigh... Thx for being there and even bigger thx for such a great idea by producing this article.
|
|
|
|
 |
|
 |
Solved.
Global variables to record the previous image size, although the data is probably available in other arguments.
private int iW = 400;
private int iH = 540;
and a custom redraw in the resize to avoid another resize evernt that is caused by the existing redraw function
void ImageResize(object sender, System.EventArgs e)
{
if(image.Width != iW)
{
double Scale1 = Convert.ToDouble(image.Width) / Convert.ToDouble(iW);
iW = image.Width;
iH = image.Height;
int LCount = Lines.Count;
for (int i = 0 ; i < LCount ; i++)
{
Line l = (Line)Lines[i];
MarkControl mc1 = l.mark1;
MarkControl mc2 = l.mark2;
Point p1 = new Point(Convert.ToInt16(mc1.Location.X * Scale1) ,
Convert.ToInt16(mc1.Location.Y * Scale1));
mc1.Location = p1;
Point p2 = new Point(Convert.ToInt16(mc2.Location.X * Scale1) ,
Convert.ToInt16(mc2.Location.Y * Scale1));
mc2.Location = p2;
l.mark1 = mc1;
l.mark2 = mc2;
}
// // custom redraw, as redraw void causes another resize!
Graphics.FromImage(image.Image).Clear(Color.Transparent);
foreach(Line l in Lines)
{
DrawLine(l);
}
image.Refresh();
}
}
|
|
|
|
 |
|
 |
i have no enouht time to read it throuth, but i can see that you use double buffer to draw your line.
If your drawing lines are so many that you will feel slowly to refresh the picture.In Actually project, not only the so few lines,so efficency is your nature fault.
If you get anothrer idea ,send me feedback with email:nn8137@163.com
|
|
|
|
 |
|
 |
Ehm, I don't get it, nn. Speak in plain english, please, it isn't my mother language...
Sam:"Better to reign in hell, than to serve in heaven", Milton.
Max:"Heaven is a place were nothing ever happens", David Byrne.
|
|
|
|
 |