C#在两个对象之间画一条线 [英] C# Draw a line between 2 objects

查看:86
本文介绍了C#在两个对象之间画一条线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好!

在这种情况下,我有一个城市列表。我的问题是如何选择2个城市并在它们之间画一条线?我应该使用GetCity(xmouse,ymouse)等方法吗?请各位帮帮我吧!



Hello guys!
In that case I have one list with the cities. My question is how I can select 2 cities and draw a line between them? Should I use a method like GetCity(xmouse, ymouse) or something else? Please guys help me!

public partial class Form1 : Form
    {
        List<city> cities = new List<city>();
        City city;
        Graphics gr;
        public Form1()
        {
            InitializeComponent();
        }
 
        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
 
        }
 
       
 
       
 
        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
           
            
            gr = pictureBox1.CreateGraphics();
            Pen greenPen = new Pen(Color.Green, 3);
            city = new City(textBox1.Text, e.X, e.Y, greenPen);
            cities.Add(city);
            Font myFont = new Font("Verdana", 14F, FontStyle.Bold);
            foreach (City c in cities)
            {
                gr.DrawString(city.Id, myFont, Brushes.Red, e.X + 20, e.Y - 20);
            }
 
            gr.DrawEllipse(greenPen, e.X-10,e.Y-10,20,20);
            gr.FillEllipse(Brushes.Green, e.X-10, e.Y-10, 20, 20);
            
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
 
            listBox1.Items.Clear();
            foreach (City c in cities)
            {
                listBox1.Items.Add(c.AsString());
            }
        }
 
      
 
        private void button2_Click(object sender, EventArgs e)
        {
           /* Pen greenPen = new Pen(Color.Green, 3);
            foreach (City ct in cities)
            {
                gr.DrawLines(cities);
            }*/
 
            //Point[] citiesp = new Point[cities.Count];

           
            //Pen greenPen = new Pen(Color.Green, 3);
            //Point pt1 = new Point(city.X, city.Y);
            //Point pt2 = new Point(20,30);
            //Point[] pcities = new Point[cities.Count];
            //int i = 0;
            //foreach (City ct in cities)
            //{
            //    pcities[i++] = new Point(ct.X, ct.Y);
            //}
                    
            //gr.DrawLines(greenPen, pcities);
        }
    }



< img src ='http://s23.postimg.org/vr16okjg7/help.jpg' border ='0'alt =help/>

推荐答案

你究竟是怎么做的取决于你,以及你在你的City class - 但我注意到City构造函数接受了X和Y的位置:

Exactly how you do it depends on you, and what you have put in your City class - but I notice that the City constructor accepts and X and Y position:
city = new City(textBox1.Text, e.X, e.Y, greenPen);

所以你可以在City类中拥有一个公共的Location属性:

So you could just have a public Location property in the City class:

public Point Location ( get; private set; }

当你想在它们之间画线时使用它。

你在构造函数中所要做的就是:

And use that when you want to draw the line between them.
All you have to do in your constructor is:

Location = new Point(x, y);



绘制线条变得微不足道:


And drawing the line becomes trivial:

gr.DrawLine(greenPen, firstCity.Location, secondCity.Location);







不,我想从中获取坐标(x,y)组合框中的对象。




"No I want to get just the coordinates(x,y) from the objects in the combobox.

private void button2_Click(object sender, EventArgs e)
        {
            
            foreach (City c in m.Cities)
            {
                listBox1.Items.Add(c.AsString());
                comboBox1.Items.Add(c.Id);
                comboBox2.Items.Add(c.Id);
            }
            m.Cities.Clear();
            
        }
 
        private void comboBox1_SelectedValueChanged(object sender, EventArgs e)
        {
           //City citycombo = comboBox1.SelectedItem as City;
            //City ct = new City("Sofia", 50, 50, Pens.Black);
            comboBox2.Items.Remove(comboBox1.SelectedItem);
            //label1.Text = "Starting point: " + ct.Id;
        }
 
        private void comboBox2_SelectedValueChanged(object sender, EventArgs e)
        {
            comboBox1.Items.Remove(comboBox2.SelectedItem);
            label2.Text = "End point: " + comboBox2.SelectedItem.ToString();
        }





我尝试了注释代码,但它说我没有引用某个对象。






好​​的......那里有些奇怪......

你为什么要删除所选的每次选择改变时,组合框中的项目会出现什么变化?Combobox肯定会很快用完项目?你不应该把旧项目放回去吗?



现在,对你的问题 - 它比你想象的更容易修复,而且更复杂一点!:笑:



我希望你改变你的City类,并添加覆盖方法(你有没有覆盖它们?)



I tried the commented code but it said that I have no reference to an object."



OK...there are some oddities there...
Why are you removing the selected item from the combobox each time the selection changes? Surely the Combobox is going to run out of items rather quickly? Shouldn't you be putting the "old" items back in?

Now, to your problem - and it's both simpler to fix than you think, and a little more complex! :laugh:

I want you to change your City class, and add an override method (Have you covered them yet?)

public override string ToString()
    {
    return ...
    }

现在,删除AsString方法的内容,并将它们移动到ToString,replaci我没有完成返回行。几乎可以肯定,它现在看起来像这样:

Now, remove the contents of your AsString method, and move them into ToString, replacing the return line I didn't complete. Almost certainly, it will now look something like this:

public override string ToString()
    {
    return CityName;
    }

现在你可以完全摆脱AsString方法,(如果你在这里没有显示的代码中使用它,将名称改为ToString)

现在发生的事情是,每当C#想要将您的City实例用作字符串时,它会自动为您调用ToString - 这意味着此代码可以更改:

You can now get rid of the AsString method completely, (and if you use it in code you haven't shown here, change the name to ToString)
What happens now is that whenever C# wants to use your City instance as a string, it will automatically call ToString for you - which means that this code can change:

private void button2_Click(object sender, EventArgs e)
        {
            
            foreach (City c in m.Cities)
            {
                listBox1.Items.Add(c);
                comboBox1.Items.Add(c);
                comboBox2.Items.Add(c);
            }
            m.Cities.Clear();
            
        }

这样做是为了让系统使用文本框中的城市名称和组合框, 因为它们会自动调用ToString你。

现在,当您从组合框中获取SelectedValue时,您可以将其直接投射到城市的实际实例:

What that does is get the system to use the name of the city in the textbox and the comboboxes, because they will automatically call ToString for you.
Now, when you fetch the SelectedValue from the combobox, you can cast it straight to the actual instance of the City:

private void comboBox1_SelectedValueChanged(object sender, EventArgs e)
    {
    City citycombo = comboBox1.SelectedItem as City;
    if (citycombo != null)
        {
        comboBox2.Items.Remove(citycombo);
        label1.Text = "Starting point: " + citycombo;
        }
    }

它应该全部开始工作......

And it should all start to work...


是的,你必须实现一个方法像那样,即 GetCity(xmouse,ymouse)。这是一个非常简单的任务:你必须找到最接近< code> {xmouse,ymouse} 的城市并选择它(如果它足够接近)。 '接近'是通过距离(或更简单的平方距离: {xmouse-xcity)*(xmouse-xcity)+(ymouse-ycity)*(ymouse-ycity))。
Yes, you have to implement a method like that, namely GetCity(xmouse, ymouse). It is a pretty straightforward task: you have to find the city most close to <code>{xmouse, ymouse} and pick it (if it is enough close to). 'Close to' is measured by the distance (or the simpler squared-distance: {xmouse-xcity)*(xmouse-xcity)+(ymouse-ycity)*(ymouse-ycity) ).


这篇关于C#在两个对象之间画一条线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆