9 Replies - 11188 Views - Last Post: 10 May 2011 - 12:57 PM Rate Topic: -----

#1 RevTorA  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 76
  • View blog
  • Posts: 246
  • Joined: 22-April 11

Displaying Images in a List View

Posted 09 May 2011 - 01:49 PM

Hello all. I'm attempting to fill a ListView I have on a form with a list of Tiles that I've extracted from a tileset image. I'm embarrassed to show my attempt, but I really have no clue how ListViews work, even after reading through all the MSDN documentation X(. So here's my current attempt. Unfortunately, nothing appears in the ListView.

private void frmEditor_Load(object sender, EventArgs e)
        {
            tileSet = new TileSet("tileset.xml", 32);
            tileListView.SmallImageList = tileSet.GetImageList();

            for (int i = 0; i < tileListView.SmallImageList.Images.Count; i++)
            {
                ListViewItem item = new ListViewItem(tileSet.GetTileID(i).ToString(), i);
                tileListView.Items.Add(item);
            }
        }



namespace MapEditor
{
    public class TileSet
    {
        private System.Drawing.Image tileSetImage;
        private int tileSize;

        class Tile
        {
            public Rectangle tileRectangle;
            public int id;
        }

        List<Tile> tiles;

        public TileSet(string filename, int tileSize)
        {
            this.tileSize = tileSize;
            LoadTileSet(filename); 
        }

        private void LoadTileSet(string filename)
        {
            using (XmlReader reader = XmlReader.Create(filename))
            {
                while (reader.Read())
                {
                    if (reader.IsStartElement())
                    {
                        switch (reader.Name)
                        {
                            case "imagefile":
                                tileSetImage = System.Drawing.Image.FromFile(reader["path"]);
                                break;

                            case "tile":
                                Tile newTile = new Tile();
                                int x = int.Parse(reader["x"]);
                                int y = int.Parse(reader["y"]);
                                int id = int.Parse(reader["id"]);

                                newTile.tileRectangle = new Rectangle(x * tileSize, y * tileSize, tileSize, tileSize);
                                newTile.id = id;

                                tiles.Add(newTile);
                                break;
                        }
                    }
                }
            }
        }

        public ImageList GetImageList()
        {
            ImageList list = new ImageList();
            list.ImageSize = new System.Drawing.Size(32, 32);

            int x, y;
            foreach (Tile tile in tiles)
            {
                x = tile.tileRectangle.X;
                y = tile.tileRectangle.Y;
                list.Images.Add(CopyBitmap(tileSetImage, new System.Drawing.Rectangle(x, y, tileSize, tileSize)));
            }

            return list;
        }

        protected System.Drawing.Image CopyBitmap(System.Drawing.Image source, System.Drawing.Rectangle part)
        {
            System.Drawing.Image bmp = new System.Drawing.Bitmap(part.Width, part.Height);
            System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmp);
            g.DrawImage(source, 0, 0, part, System.Drawing.GraphicsUnit.Pixel);
            g.Dispose();
            return bmp;
        }

        public int GetTileID(int index)
        {
            return tiles[index].id;
        }
    }
}



A big mess I know, but I'm hoping that maybe somebody who's familiar with windows forms could give me some insight into how I might accomplish what I'm trying to do. Any ideas?

Is This A Good Question/Topic? 0
  • +

Replies To: Displaying Images in a List View

#2 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 982
  • Posts: 969
  • Joined: 30-September 10

Re: Displaying Images in a List View

Posted 09 May 2011 - 02:16 PM

Hi,

Assuming GetImageList() is actually returning a list filled with viewable images, try setting the ListView.View property.

It is set to View.LargeIcon by default. Seeing as your using a SmallImageList, try setting it to View.SmallIcon (View.List should work also; which one you use depends on how you want your ListView to be laid out :)).

this.tileListView.View = View.List;

//OR

this.tileListView.View = View.SmallIcon;


This post has been edited by CodingSup3rnatur@l-360: 09 May 2011 - 02:42 PM

Was This Post Helpful? 0
  • +
  • -

#3 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5316
  • View blog
  • Posts: 11,357
  • Joined: 02-June 10

Re: Displaying Images in a List View

Posted 09 May 2011 - 02:30 PM

Do you really need it to be in a ListView?
Could you perhaps use a Panel or FlowLayoutPanel? That might reduce the complication.

foreach (Tile tile in tiles)
            {
                x = tile.tileRectangle.X;
                y = tile.tileRectangle.Y;
                list.Images.Add(CopyBitmap(tileSetImage, new System.Drawing.Rectangle(x, y, tileSize, tileSize)));
            }



Do you mean to be getting an image from 'tileSetImage' and not from the 'tile' iteration of your loop?

Wouldn't you be getting tile.Image? Shouldn't your Tile object contain a .Image property so you can easily retrieve it? Maybe a look at the archetecture is in order.

A Tile has an image.
TileSet would be a list of Tiles... List<Tile> TileSet

So getting a specific image would be as easy as


TileSet[4].Image

This post has been edited by tlhIn`toq: 09 May 2011 - 02:31 PM

Was This Post Helpful? 0
  • +
  • -

#4 RevTorA  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 76
  • View blog
  • Posts: 246
  • Joined: 22-April 11

Re: Displaying Images in a List View

Posted 09 May 2011 - 02:58 PM

View PostCodingSup3rnatur@l-360, on 09 May 2011 - 02:16 PM, said:

Hi,

Assuming GetImageList() is actually returning a list filled with viewable images, try setting the ListView.View property.

It is set to View.LargeIcon by default. Seeing as your using a SmallImageList, try setting it to View.SmallIcon (View.List should work also; which one you use depends on how you want your ListView to be laid out :)).

this.tileListView.View = View.List;

//OR

this.tileListView.View = View.SmallIcon;



I made sure to set View to SmallIcon yes. In the properties window anyway, which should mean it's set that way in the code.

View PosttlhIn`toq, on 09 May 2011 - 02:30 PM, said:

Do you really need it to be in a ListView?
Could you perhaps use a Panel or FlowLayoutPanel? That might reduce the complication.

foreach (Tile tile in tiles)
            {
                x = tile.tileRectangle.X;
                y = tile.tileRectangle.Y;
                list.Images.Add(CopyBitmap(tileSetImage, new System.Drawing.Rectangle(x, y, tileSize, tileSize)));
            }



Do you mean to be getting an image from 'tileSetImage' and not from the 'tile' iteration of your loop?

Wouldn't you be getting tile.Image? Shouldn't your Tile object contain a .Image property so you can easily retrieve it? Maybe a look at the archetecture is in order.

A Tile has an image.
TileSet would be a list of Tiles... List<Tile> TileSet

So getting a specific image would be as easy as


TileSet[4].Image


I'm not sure how I would use a panel to accomplish this. The thing is, I want the use to select the tile like they might an item in a ListBox (I really wish I could just display the images in here, but can't right?).

As for why I don't have an image inside the Tile class, it was either parse each individual image using the CopyBitmap method while loading the tileset, or when forming the ImageList... I just chose the latter... just because lol. I'll consider changing it however.
Was This Post Helpful? 0
  • +
  • -

#5 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5316
  • View blog
  • Posts: 11,357
  • Joined: 02-June 10

Re: Displaying Images in a List View

Posted 10 May 2011 - 04:58 AM

If your panel has a bunch of Tile objects on it, you can then handle the .Clicked event.

I presume that the same response would be required for all Tiles. So if the Tile is clicked on, you handle it. Put the responsibility in the right object. That's just part of OOP.

Look at it this way... If you have a collection of cars that need gas you fill up each one individually. It has a method of Car.FillTank(). You don't pour gas into the parkinglot (the container of all the car objects) and have a method of ParkingLot.DistributeGas()

We try to make the objects as complete and feature-rich as possible so they can take care of themselves. Like children. Rather than have a higher parent object take care of them for their entire life.

If you already have a Tile object, and you have a collection of them... It is silly to also have to keep a synchronize collection of images, or to have some other control (like the listview) handle their actions for them.
Was This Post Helpful? 0
  • +
  • -

#6 RevTorA  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 76
  • View blog
  • Posts: 246
  • Joined: 22-April 11

Re: Displaying Images in a List View

Posted 10 May 2011 - 07:22 AM

Aye, but what to use for the tile objects in the panel? Are you thinking a custom control? 'Cause I'm really new to Windows Forms programming (*gasp*). Or maybe a bunch of picture boxes? If the latter, how would I dynamically fill the panel with picture boxes? If you need to give a me a "RTFM" and a link then I'll gladly read anything you throw at me lol.
Was This Post Helpful? 0
  • +
  • -

#7 modi123_1  Icon User is online

  • Suitor #2
  • member icon



Reputation: 8375
  • View blog
  • Posts: 31,132
  • Joined: 12-June 08

Re: Displaying Images in a List View

Posted 10 May 2011 - 07:35 AM

why not show the images in a single columned grid? Plunk a grid down, add a 'data grid view image column' and fill that? It sounds liket that would capture all our needs without you making a custom user control.
Was This Post Helpful? 0
  • +
  • -

#8 tlhIn`toq  Icon User is offline

  • Please show what you have already tried when asking a question.
  • member icon

Reputation: 5316
  • View blog
  • Posts: 11,357
  • Joined: 02-June 10

Re: Displaying Images in a List View

Posted 10 May 2011 - 08:02 AM

View PostRevTorA, on 10 May 2011 - 08:22 AM, said:

Aye, but what to use for the tile objects in the panel? Are you thinking a custom control? 'Cause I'm really new to Windows Forms programming (*gasp*). Or maybe a bunch of picture boxes? If the latter, how would I dynamically fill the panel with picture boxes? If you need to give a me a "RTFM" and a link then I'll gladly read anything you throw at me lol.


Yes, exactly. In object oriented programing you orient your programming to objects.
Since you were already using Tiles and TileSets I thought you were already doing this.

I think you will save yourself a lot of time and headache by doing a couple tutorials before you proceed. Otherwise you're going to build an app based on little understanding of the right way to do it, waste a lot of time and effort, just to realize there had to be a better way. Then you'll end up doing the tutorials anyway and starting all over.

The tutorials below walk through making an application including inheritance, custom events and custom controls.
Bulding an application - Part 1
Building an application - Part 2

You make a Tile class as your custom object. It could be inherited from PictureBox class if you like just to make things easy because then it will already have a .Image property, a .Click event and so on.

Now when you add a Tile instance such as myTile to a control like a panel it will be able to act as you need it to. It will show a picture. It will react to a .Click event. (remember the 'sender' of an event is the object itself. So you can just use the sender to get everything you need from whomever sent the event.)

Here is another analogy to think about...

If you were building an animal shelter you don't make the shelter micromanage all the animal objects. You make an 'animal' class. You inherit a 'dog' class from 'animal'. You inherit a 'cat' class from 'animal'. Then you make instances of the 'dog' class and give them .Name's like Fido and Butch. You don't try to make the shelter synchronize with a giant list of WhoseBeenFed. You loop through each dog instance and run the .Feed() method, setting its .BeenFed property to true. Now you can at any time check a given instance to see if it has been fed.
if (Butch.BeenFed) Butch.TakeForWalk();


In your own programs the parent application doesn't micromanage all the buttons, right?
You check a property of a given instance

Button btnStart = new Button();
btnStart.Image = properties.GreenLED;
btnStatt.Click += StartButtonHandler;


After a while it becomes natural to see the world and your projects as a collection of objects within collections of objects.
  • An address book is made up of contacts.A contact is made up of a person, a List<> of PhoneNumbers, a List<> of addresses, a DateTime for birthday and so on.
  • A truck is inherited from 'vehicle' which already had common properties for 'Color', 'Maker' and 'NumberOfDoors' and contains an 'engine' object with its own properties for 'CylinderCount' and so on


Learning to program at the object level is vital. Just because you haven't done it before is no reason to not learn now. Take the plunge, embrace it. Because doing it now will save you hundreds of hours down the line.


Standard resources, references and suggestions for new programmers.


I would recommend you start with "Hello World" just like the other million+ coders out there. Then work your way up to the more advanced tasks like this.

The problem with taking on large, complex tasks like this when you are new to coding is that
  • it will frustrate you to the point of quitting,
  • you don't know enough about coding to know where to start or in what direction to design your program
  • You risk learning via the 'Swiss cheese' method where you only learn certain bits and pieces for the one project but have huge holes in your education.


I am going to guess that you are trying to teach yourself C# without much guidance, a decent book or without knowing where to look. Sometimes just knowing where to look can make all the difference. Google is your friend.
Search with either "C#" or "MSDN" as the first word: "MSDN Picturebox", "C# Custom Events", "MSDN timer" etc.

But honestly, just typing away and seeing what pops up in Intellisense is going to make your self-education take 20 years. You can learn by trying to reverse engineer the language through banging on the keyboard experimentation - or you can learn by doing the tutorials and following a good "How to learn C#" book.

Free editions of Visual Studio 2010

May I suggest picking up a basic C# introductory book? There are so many great "How do I build my first application" tutorials on the web... There are dozens of "Learn C# in 21 days", "My first C# program" type books at your local book seller or even public library.

D.I.C. C# Resource page Start here
Intro to C# online tutorial then here...
C# control structures then here.
MSDN Beginner Developer video series
MSDN video on OOP principals, making classes, constructors, accessors and method overloading
MSDN Top guideline violations, know what to avoid before you do it.

The tutorials below walk through making an application including inheritance, custom events and custom controls.
Bulding an application - Part 1
Building an application - Part 2
Quick and easy custom events
Passing values between forms/classes

Working with environmental variables

Debugging tutorial
Debugging tips
Great debugging tips
It still doesn't work, article

Build a Program Now! in Visual C# by Microsoft Press, ISBN 0-7356-2542-5
is a terrific book that has you build a Windows Forms application, a WPF app, a database application, your own web browser.

C# Cookbooks
Are a great place to get good code, broken down by need, written by coding professionals. You can use the code as-is, but take the time to actually study it. These professionals write in a certain style for a reason developed by years of experience and heartache.

Microsoft Visual Studio Tips, 251 ways to improve your productivity, Microsoft press, ISBN 0-7356-2640-5
Has many, many great, real-world tips that I use all the time.

Writing a text file is always one of the first things people want to do, in order to store data like high-scores, preferences and so on
Writing a text file tutorial.
Reading a text file tutorial.


These are just good every-day references to put in your bookmarks.
MSDN C# Developers Center with tutorials
Welcome to Visual Studio

Have you seen the 500+ MSDN Code Samples? They spent a lot of time creating samples and demos. It seems a shame to not use them.

Let me also throw in a couple tips:
  • You have to program as if everything breaks, nothing works, the cyberworld is not perfect, the attached hardware is flakey, the network is slow and unreliable, the harddrive is about to fail, every method will return an error and every user will do their best to break your software. Confirm everything. Range check every value. Make no assumptions or presumptions.
  • Take the extra 3 seconds to rename your controls each time you drag them onto a form. The default names of button1, button2... button54 aren't very helpful. If you rename them right away to something like btnOk, btnCancel, btnSend etc. it helps tremendously when you make the methods for them because they are named after the button by the designer.
    btnSend_Click(object sender, eventargs e) is a lot easier to maintain than button1_click(object sender, eventargs e)
  • You aren't paying for variable names by the byte. So instead of variables names of a, b, c go ahead and use meaningful names like Index, TimeOut, Row, Column and so on

This post has been edited by tlhIn`toq: 10 May 2011 - 08:03 AM

Was This Post Helpful? 1
  • +
  • -

#9 RevTorA  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 76
  • View blog
  • Posts: 246
  • Joined: 22-April 11

Re: Displaying Images in a List View

Posted 10 May 2011 - 12:25 PM

You sir are a god amongst men (or C# programmers at least :P). I'm actually pretty familiar with C# (at least I thought I was), and to OOP, I just hadn't really used it in a GUI setting before. I'm completely new to Windows.Forms, and the last time I used a form designer was VB 4.0 (yes, 10 years ago :(). Thank you so much for all the links, I've already read though a lot of 'em and am trying to wrap my head around some of the harder topics (Events and Event Handlers still get me, as well as Delegates, though Events basically are delegates so I guess that explains that hehe).

Thank you much :)

This post has been edited by RevTorA: 10 May 2011 - 12:25 PM

Was This Post Helpful? 0
  • +
  • -

#10 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4312
  • View blog
  • Posts: 7,467
  • Joined: 08-June 10

Re: Displaying Images in a List View

Posted 10 May 2011 - 12:57 PM

If delegates are tripping you up, give this a read:

http://www.dreaminco...das-and-events/

it's a tutorial by CodingSup3rnatur@l-360, and it does a great job explaining delegates, lambdas, and events.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1