[教程 9] 手形工具(第二部分)导航器面板





5.00/5 (1投票)
我们将继续实现手柄工具的功能,添加一个用作地图的导航面板,我们还将有一个红色矩形,告诉用户他实际正在查看整个窗体的哪个区域,它还可以用来平移窗体。
引言
这是第九篇教程,该系列教程教程是关于如何使用 C# 在Windows窗体中构建图形程序,该程序将艺术品导出为矢量格式。
- 教程1---https://codeproject.org.cn/Tips/1082353/tut-GDIplus-Artwork-from-svg
- 教程2---https://codeproject.org.cn/Tips/1082633/interactivaly-add-multiple-shapes-using-linked-lis
- 教程3---https://codeproject.org.cn/Tips/1084073/tut-graphics-program-using-Csharp-Drag-Drop-Delete
- 教程4---https://codeproject.org.cn/Tips/1105143/tut-Draw-Lines-with-Circle-and-Rectangle-End
- 教程5---https://codeproject.org.cn/Tips/1105495/tut-form-communication-multi-tab-program-custom-cu
- tut6---https://codeproject.org.cn/Tips/1106645/tut-Line-Drag-Drop-Line-Selection
- tut7---https://codeproject.org.cn/Tips/1108018/tut-Drag-Drop-points-in-lines
- tut8---https://codeproject.org.cn/Tips/1108967/tut-Hand-tool
......此外,您还将了解如何移动、删除、撤销(ctrl z)您的矢量艺术作品,并将其保存为一种特殊格式,以便您的程序可以再次读取。
此外,我们将学习如何保存 XML 文件... 如何导出为 Verilog 格式... 如何使用星形算法... 如何使用手形工具... 如何手动创建撤销技术。
您将能够构建什么
- https://drive.google.com/folderview?id=0B739QmcCMLMHVU1DbHhIQlZ3MTA&usp=sharing
- https://www.youtube.com/watch?v=6hXJ1EoAYc0
我们将继续实现手柄工具的功能,添加一个用作地图的导航面板。
我们还将有一个红色矩形,告诉用户他实际正在查看整个窗体的哪个区域,它还可以用来平移窗体。
这个导航面板将能够:当您平移窗体时,导航面板会更新
它还将允许用户单击导航面板中的任何位置,窗体将被平移
它还将允许用户拖放红色矩形,这将平移窗体
背景
- 教程1---https://codeproject.org.cn/Tips/1082353/tut-GDIplus-Artwork-from-svg
- 教程2---https://codeproject.org.cn/Tips/1082633/interactivaly-add-multiple-shapes-using-linked-lis
- 教程3---https://codeproject.org.cn/Tips/1084073/tut-graphics-program-using-Csharp-Drag-Drop-Delete
- 教程4---https://codeproject.org.cn/Tips/1105143/tut-Draw-Lines-with-Circle-and-Rectangle-End
- 教程5---https://codeproject.org.cn/Tips/1105495/tut-form-communication-multi-tab-program-custom-cu
- tut6---https://codeproject.org.cn/Tips/1106645/tut-Line-Drag-Drop-Line-Selection
- tut7---https://codeproject.org.cn/Tips/1108018/tut-Drag-Drop-points-in-lines
- tut8---https://codeproject.org.cn/Tips/1108967/tut-Hand-tool
教程地图
- 在
super_form
中添加一个tab control
。 - 创建一个名为
Navigator_form
的窗体,编辑其一些属性,然后将其添加到super_form
中的tab control
。 - 在
super_form
中,将一些变量更改为static
。 - 在
Navigator_form
中,创建一个按钮并为其添加一个单击函数来刷新navigator_form
,然后在Form1
的Onpaint
中工作以刷新导航窗体。 - 在
Navigator_form
中,处理缩放图形的比例值,以便大图形(形状和线条)可以在Navigator_form
中的较小区域内查看。 - 在
Navigator_form
中,使用OnPaint
函数来查看形状和线条。 - 在
Navigator_form
中创建一个红色矩形,并根据form
中的滚动值来移动它。 - 在
Navigator_form
中,创建一个MouseDown
函数,以实现用户单击导航面板中的任何位置,窗体将被平移的功能。 - 在
Navigator_form
中,创建一个MouseMove
函数,以实现用户拖放红色矩形,这将平移窗体的功能。
1-在super_form
中添加一个tab control
。
从工具箱中获取 tab_control。
将其添加到super_form[Design]
中的旧 tabcontrol 的左侧。
从新添加的tab_control
的属性中,单击tabPages
。
删除tabPages
中的所有页面。
2-创建一个名为Navigator_form
的窗体,编辑其一些属性,然后将其添加到super_form
中的tab control
。
创建一个名为Navigator_form
的窗体。
编辑其一些属性。
将其背景颜色更改为白色。
并为此窗体创建一个特殊光标,当鼠标进入此窗体时,光标将更改,我们将其设为默认的手形光标。
更改窗体边框大小,因为我们不需要。
但我们需要它为
因此,我们将更改Navigator_form
的属性。
我们将调整其大小为。
现在我们需要将这个新创建的窗体添加到super_form
中的tabControl
。
所以,在super_form
的构造函数中进行操作。
public super_form()
{
InitializeComponent();
.
.//old code
.
//new code
Navigator_form nav = new Navigator_form(); //create a new object of Navigator_form
AddNewTab_nav(nav); //would be discussed
//new code
}
现在我们需要创建实际的函数,将窗体添加到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);
//tabControl2 is the tabControl that we have just created
}
3-在super_form
中,将一些变量更改为static
。
让指示哪个窗体被选中的integer
为static
,以便在navigator_form
中使用,因为我们需要导航窗体作为唯一选中窗体的地图,因为我们需要导航窗体作为每个窗体的地图。
public static int selected_tab=0;
并将 form_list 更改为 static。
public static List<Form1> form_list=new List<Form1>();
4-在Navigator_form
中,创建一个按钮并为其添加一个单击函数来刷新navigator_form
,然后在Form1
的Onpaint
中工作以刷新导航窗体。
由于我们需要从另一个窗体调用 Onpaint 函数,我们需要 Onpaint 函数为 static,但这无法实现,因此有一个解决方法,即通过将单击函数放在一个 static 按钮上,并在该单击函数内调用 Onpaint。
所以,首先让我们创建一个 Onpaint。
然后我们将创建一个 static 按钮。
public static Button invalidate_button=new Button();
然后在Navigator_form
的构造函数中,为此按钮分配一个单击函数。
public Navigator_form()
{
InitializeComponent();
invalidate_button.Click += Invalidate_button_Click;
}
这个函数将简单地刷新窗体。
private void Invalidate_button_Click(object sender, EventArgs e)
{
Invalidate();
}
然后,在Form1
的OnPaint
函数中,我们将简单地调用该按钮的单击函数来刷新Navigator_form
。
protected override void OnPaint(PaintEventArgs e)
{
.
.//old code
.
Navigator_form.invalidate_button.PerformClick();
}
5-在Navigator_form
中,处理缩放图形的比例值,以便大图形(形状和线条)可以在Navigator_form
中的较小区域内查看。
首先,在Navigator_form
中创建两个新的 int。
double div_h;
double div_w;
在Navigator_form
的构造函数中。
public Navigator_form()
{
InitializeComponent();
invalidate_button.Click += Invalidate_button_Click;
DoubleBuffered = true; //to make the drawing more smooth
Form1 selected_form = super_form.form_list.ElementAt<Form1>(super_form.selected_tab);
//know which form is selected , use the static selected_tab
Size siize = selected_form.AutoScrollMinSize;//get size of the selected form
div_h = (double)this.Size.Height /(double) siize.Height ;
div_w = (double)this.Size.Width / (double)siize.Width ;
//divide the size of the navigator form by the size of the selected form
//do it for horizontal and vertical
div_h = Math.Round(div_h, 1);
div_w = Math.Round(div_w, 1);
//approximate to the first decimal place
//if it was 0.19523---> 0.2
}
6-在Navigator_form
中,使用OnPaint
函数来查看形状和线条。
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);
//know which form is selected , use the static selected_tab
Matrix m = new Matrix();//to scale down the graphics we would use a Matrix
m.Scale((float)div_h, (float)div_w, MatrixOrder.Append);
//define the matrix with values previously calculated
g.Transform = m;
//actually scale down te graphics
//draw the lines
foreach (lines l in selected_form.lines_list)
{
g.DrawPath(l.pen, l.path_line);
g.FillPath(Brushes.Black, l.arrow_path_line);
}
//draw the shapes
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-在Navigator_form
中创建一个红色矩形,并根据form
中的滚动值来移动它。
在Navigator_form
中,创建一个矩形。
public Rectangle border = new Rectangle();
然后在Navigator_form
中,编辑OnPaint
。
private void Navigator_form_Paint(object sender, PaintEventArgs e)
{
.
.//old code
.
//first calculate the location of the red rectangle which would simply
// be the opposite of the scroll value of the selected form
Point offset_point = new Point(-selected_form.AutoScrollPosition.X,
-selected_form.AutoScrollPosition.Y);
border.Location = offset_point;
//set the size of the red rectangle to be the same size of what the user
//can see without panning which is 1000 * 700
//don't forget that all graphics would be scaled down
Size siize = new System.Drawing.Size(1000, 700);
border.Size = siize;
//then draw the rectangle in a red color
e.Graphics.DrawRectangle(new Pen(Brushes.Red, 1), border);
}
现在,当在Form1
中工作时,导航器将被刷新。
现在我们需要扩展导航窗体的功能,以实现单击和拖放红色矩形。
8-在Navigator_form
中,创建一个MouseDown
函数,以实现用户单击导航面板中的任何位置,窗体将被平移的功能。
在Navigator_form
中创建一个MouseDown
函数。
然后在Navigator_form
的后台代码中,在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);
//know which form is selected , use the static selected_tab
Point p = new Point(e.Location.X * 5, e.Location.Y * 5);
//get the position of the mouse
//and scale it up by multiplying it by 5, because we have scaled down the graphics before
selected_form.AutoScrollPosition = p;
//move (pan) the selected form
}
所以结果将是。
9-在Navigator_form
中,创建一个MouseMove
函数,以实现用户拖放红色矩形,这将平移窗体的功能。
在Navigator_form
中创建一个MouseMove
函数。
然后在Navigator_form
的后台代码中,在Navigator_form_MouseMove
中。
private void Navigator_form_MouseMove(object sender, MouseEventArgs e)
{
//only work when the mouse moves and clicks the left button
//would implement the drag & drop functionality
if (e.Button == MouseButtons.Left)
{
//same code as in function of Navigator_form_MouseDown
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;
}
}
所以结果将是。
如果您喜欢这个教程,请投赞成票