tags:

views:

60

answers:

2

Hi,

I am drawing a list of file & folder names on a panel and I'm trying to brainstorm the best way to detect if and when a user clicks a file/folder name, as well as what file or folder name they actually clicked.

Below are the methods I wrote so far. My first thought was to piggy back each piece of text with a transparent control and dynamically wire up an onclick event that way. But it seems like a waste of resources.

private void DisplayFolderContents(ListBox lb, string sPath)
 {
  lblPath.Text = sPath;
  const float iPointX = 01.0f;
  float iPointY = 20.0f;
  DirectoryContents = FileSystem.RetrieveDirectoriesAndFiles(sPath, true, true, "*.mp3");

  foreach (string str in DirectoryContents)
  {
   DrawString(FileSystem.ReturnFolderFromPath(str), iPointX, iPointY, 21, panListing);


   iPointY += 50;
  }
 }


private void DrawString(string textToDraw, float xCoordinate, float yCoordinate, int fontSize, Control controlToDrawOn)
 {

  Graphics formGraphics = controlToDrawOn.CreateGraphics();
  formGraphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
  Font drawFont = new Font(
    "Arial", fontSize, FontStyle.Bold);

  SolidBrush drawBrush = new
    SolidBrush(Color.White);

  formGraphics.DrawString(textToDraw, drawFont, drawBrush, xCoordinate, yCoordinate);

  drawFont.Dispose();
  drawBrush.Dispose();
  formGraphics.Dispose();
 }

Thanks, Kevin

+2  A: 

First of all, keep a list of every string or object drawn on your panel with their location and size.

After that, handle the event MouseDown or MouseUp (depending of the behavior you want)

List<YourObject> m_list; //The list of objects drawn in the panel.

private void OnMouseDown(object sender, MouseEventArgs e)
{
    foreach(YourObject obj in m_list)
    {
        if(obj.IsHit(e.X, e.Y))
        {
            //Do Something
        }
    }
}

In the class YourObject implements the function IsHit:

public class YourObject
{

    public Point Location { get; set; }
    public Size Size {get; set; }

    public bool IsHit(int x, int y)
    {
        Rectangle rc = new Rectangle(this.Location, this.Size);
        return rc.Contains(x, y);
    }
}

It is not necessary to create the rectangle every time, you could have a class variable to keep this information. It is just important to update your rectangle when the location or the size change.

Francis B.
Thank you. This did answer the question I asked.
Kevin
+2  A: 

I knew I was missing an obvious solution. I can draw the text onto a buttor or other control, and wire it up that way. Doh!

Kevin
This is a better approach, because you can use the control layering to handle the z-order for you.
MusiGenesis