Make button map?

How can I do the following: I am not asking for a specific code, but I need some direction, since I have been racking my brains for a long time. I just want to make a map, for example. The United States, and each state, is a different picture or region that you can stick and click. I tried to play with png and transparencies, but I'm at a dead end. More ambitiously, I would like to drag labels with state capital over each state and drop them there, then there is a process where, if the label / capital corresponds to the state, then this is not so.

I tried GIS (?) I want to do this in C #, but I cannot figure out how to do this. Can anyone help? Is it too complicated in C #? Should I use a different approach? Please, what approach?

-1
source share
1 answer

The good news: the software part is not so complicated and even with good old Winforms you can perform basic checks in a few lines. However, clickable areas cannot be buttons in Winforms.

Here are two solutions:

Solution 1 . You can define a list of areas called areas and check if someone clicked.

Here's the start: I define very simple Rectangle Regionand not very simple Polygon Regionand check every click if it is hit. If this was deleted, I would output its data to the header text of the form:

//..
using System.Drawing.Drawing2D;
//..
public Form1()
{
    InitializeComponent();
    // most real states don't look like rectangles
    Region r = new Region(new Rectangle(0, 0, 99, 99));
    regions.Add(r);
    List<int> coords = new List<int>() {23,137, 76,151, 61,203, 
                       117,283, 115,289, 124,303, 112,329, 76,325, 34,279, 11,162};
    List<Point> points = new List<Point>();
    for (int i = 0; i < coords.Count ; i += 2) 
                        points.Add(new Point(coords[i], coords[i+1]));
    byte[] fillmodes = new byte[points.Count];
    for (int i = 0 ; i < fillmodes.Length; i++) fillmodes[i] = 1;
    GraphicsPath GP = new GraphicsPath(points.ToArray(), fillmodes);
    regions.Add(r);

}

List<Region> regions = new List<Region>();


private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
    using (Graphics G = pictureBox1.CreateGraphics() )
    foreach(Region r in regions)
    {
        Region ri = r.Clone();
        ri.Intersect(new Rectangle(e.X, e.Y, 1, 1));
        if (!ri.IsEmpty(G))  // hurray, we got a hit
            { this.Text = r.GetBounds(G).ToString(); break; }
    }

}

Areas in the test program are not visible. For testing, you can add something like this:

private void button1_Click(object sender, EventArgs e)
{   // paint a non-persistent filling
    using (Graphics G = pictureBox1.CreateGraphics())
        foreach (Region r in regions)
        { G.FillRegion(Brushes.Red, r); }
}

: , , ! . , html , . , ..

: . wikipedia. , , , imo. , . !

, 78 , 50 .

2:

Dictionary<Color, string> Dictionary<Color, StateInfo>. , jpeg, .

; , ; -)

, :

Color c = ((Bitmap) pictureBox1.Image).GetPixel(e.X, e.Y)
string StateName = stateDictionary[c];

, ..

, ; , PictureBox, . imo.. !

, drag & drop. DragDrop , , Mouseup, , .

, ..!

WPF.

0

Source: https://habr.com/ru/post/1666414/


All Articles