Introduction
This is the Ninth tutorial of a series of tutorials of how to build a graphics program using C# in Windows form that exports the artwork in a vector format.
.... also, you would understand how to move, delete, ctrl z your vector art and save it in a special format to be read by your program again.
Also, we will learn how to save XML files... how to export in verilog format... how to use a star algorithm... how to use hand tool... how to manually create the ctrl z technique.
What you will be capable of building:
we will continue the functionality of the hand tool with having a navigator panel which works as a map,
we will also have a red rectangle which tells the user where he is actually viewing inside the whole form, also it can be moved to pan the form
this navigator panel would be able to : when you pan the form , the navigator panel would be updated
also it would enable the user to click at any place in the navigator panel , and the form would be panned
also it would enable the user to drag and drop the red rectangle which would pan he form
Background
Map of the tut
- add a
tab control
inside the super_form
- create a form and name it
Navigator_form
, edit some of its proprieties , and add it to the tab control
inside the super_form
- in the
super_form
change some variables to be static
- in the
Navigator_form
, create a button to have a click function to refresh the navigator_form
, and in Form1
work in the Onpaint
to refresh the navigator form
- in the
Navigator_form
work on getting the value for the graphics to be scaled down by , so that the big graphics(shapes and lines ) would view in a smaller area inside the Navigator_form
- in the
Navigator_form
work with the OnPaint
function to view the shapes and the lines
- in the
Navigator_form
create a red rectangle and move it with the value of the scroll value in the form
- in the
Navigator_form
create a MouseDown
function to make the behavior of enabling the user to click at any place in the navigator panel , and the form would be panned
- in the
Navigator_form
create a MouseMove
function to make the behavior of enabling the user to drag and drop the red rectangle which would pan he form
1-add a tab control
inside the super_form
get the tab_control from the tool box
add it in the the super_form[Desgin]
to the left of the old tabcontrol
from the proprieties of the new added tab_contol
, click on the tabPages
remove all pages inside the tabPages
2-create a form and name it Navigator_form
, edit some of its proprieties , and add it to the tab control
inside the super_form
create a form and name it Navigator_form
edit some of its proprieties
change its back color to make it white
and make a special cursor for this form, so when the mouse enters this form the cursor would be changed, lets make the default hand cursor
change the form border size as we don't need
but we need it to be
so we would change Navigator_form
proprieties
and we would change its size to be
now we need to add this newly created Form , to the tabControl
inside the super_form
so work on the constructor of super_form
public super_form()
{
InitializeComponent();
.
.
.
Navigator_form nav = new Navigator_form(); AddNewTab_nav(nav);
}
now we need to create the function itself that adds the form to the tabControl
private void AddNewTab_nav(Form frm)
{
TabPage tab = new TabPage(frm.Text);
frm.TopLevel = false;
frm.Parent = tab;
frm.Visible = true;
tabControl2.TabPages.Add(tab);
}
3-in the super_form
change some variables to be static
let the integer
that tells which form was selected to be static
,so that it would be used in the navigator_form
, as we need the navigator form to be the map of the only selected form , as we need the navigator form to be the map for each form
public static int selected_tab=0;
and change form_list to be static
public static List<Form1> form_list=new List<Form1>();
4-in the Navigator_form
, create a button to have a click function to refresh the navigator_form
, and in Form1
work in the Onpaint
to refresh the navigator form
as we would need the Onpaint function to be called from an another form , we would need the Onpaint function to be static , but this can't be done, so there is a method around this , by making the click function on a static button, and inside this click call the Onpaint
so first lets create an Onpaint
then we would create a static button
public static Button invalidate_button=new Button();
then in the constructor of the Navigator_form
, assign a click function for this button
public Navigator_form()
{
InitializeComponent();
invalidate_button.Click += Invalidate_button_Click;
}
this function would simply refresh the form
private void Invalidate_button_Click(object sender, EventArgs e)
{
Invalidate();
}
then in the Form1
in its OnPaint
function we would simply call the click function of that button to refresh the Navigator_form
protected override void OnPaint(PaintEventArgs e)
{
.
.
.
Navigator_form.invalidate_button.PerformClick();
}
5-in the Navigator_form
work on getting the value for the graphics to be scaled down by , so that the big graphics(shapes and lines ) would view in a smaller area inside the Navigator_form
first in the Navigator_form
create two new int
double div_h;
double div_w;
in the constructor of the Navigator_form
public Navigator_form()
{
InitializeComponent();
invalidate_button.Click += Invalidate_button_Click;
DoubleBuffered = true;
Form1 selected_form = super_form.form_list.ElementAt<Form1>(super_form.selected_tab);
Size siize = selected_form.AutoScrollMinSize; div_h = (double)this.Size.Height /(double) siize.Height ;
div_w = (double)this.Size.Width / (double)siize.Width ;
div_h = Math.Round(div_h, 1);
div_w = Math.Round(div_w, 1);
}
6-in the Navigator_form
work with the OnPaint
function to view the shapes and the lines
private void Navigator_form_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Form1 selected_form = super_form.form_list.ElementAt<Form1>(super_form.selected_tab);
Matrix m = new Matrix();
m.Scale((float)div_h, (float)div_w, MatrixOrder.Append);
g.Transform = m;
foreach (lines l in selected_form.lines_list)
{
g.DrawPath(l.pen, l.path_line);
g.FillPath(Brushes.Black, l.arrow_path_line);
}
foreach (shapes sh in selected_form.shape_list)
{
Svg.ISvgRenderer render = null; ;
g.DrawPath(new Pen(Brushes.Black, 2), sh.draw_svg().Path(render));
g.FillPath(Brushes.Khaki, sh.draw_svg().Path(render));
}
}
7-in the Navigator_form
create a red rectangle and move it with the value of the scroll value in the form
in the Navigator_form
, create a rectangle
public Rectangle border = new Rectangle();
and in the Navigator_form
, edit the OnPaint
private void Navigator_form_Paint(object sender, PaintEventArgs e)
{
.
.
.
Point offset_point = new Point(-selected_form.AutoScrollPosition.X,
-selected_form.AutoScrollPosition.Y);
border.Location = offset_point;
Size siize = new System.Drawing.Size(1000, 700);
border.Size = siize;
e.Graphics.DrawRectangle(new Pen(Brushes.Red, 1), border);
}
now the navigator would be refreshed when working in the Form1
now we need to expand the features of the navigator form to enable clicking and dragging and drapog the red rectangle
8-in the Navigator_form
create a MouseDown
function to make the behavior of enabling the user to click at any place in the navigator panel , and the form would be panned
in the Navigator_form
create a MouseDown
function
then in the back code in the Navigator_form
in the Navigator_form_MouseDown
private void Navigator_form_MouseDown(object sender, MouseEventArgs e)
{
Form1 selected_form = super_form.form_list.ElementAt<Form1>(super_form.selected_tab);
Point p = new Point(e.Location.X * 5, e.Location.Y * 5);
selected_form.AutoScrollPosition = p;
}
so thee result would be
9-in the Navigator_form
create a MouseMove
function to make the behavior of enabling the user to drag and drop the red rectangle which would pan he form
in the Navigator_form
create a MouseMove
function
then in the back code in the Navigator_form
in the Navigator_form_MouseMove
private void Navigator_form_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Form1 selected_form = super_form.form_list.ElementAt<Form1>(super_form.selected_tab);
Point p = new Point(e.Location.X * 5, e.Location.Y * 5);
selected_form.AutoScrollPosition = p;
}
}
so the result would be
If you liked the tut Vote it up