Jak do listBoxa dodać obrazki?

0

Jak to zrobić? Czy może nie da się i trzeba wykorzystać listView

0
maszynaz napisał(a)

Jak do listBoxa dodać obrazki?

Zależy w jakim sensie; Jeśli chodzi Ci o umieszczenie obrazu zamiast normalnego tekstu to masz przecież coś takiego jak kanwa (ang. Canvas) i możliwość rysowania po niej w zdarzeniu OnDrawItem czy podobnie nazwanych (nie piszę w C# więc nazewnictwa nie znam, stąd może się różnić od podanego przeze mnie); Najpierw jednak trzeba dostosować właściwości kontrolki (chociażby wysokość pozycji, pewnie ItemHeight i na pewno OwnerDraw);

maszynaz napisał(a)

Czy może nie da się i trzeba wykorzystać listView

Wszystko się da, tylko trzeba wiedzieć jak; W TListView też się da - zdarzenia praktycznie takie same, ale do własnego rysowania itemów masz kilka (zwykłe i rozszerzone - do bardziej zaawansowanych rzeczy);

Zastanów się z którego komponentu chcesz korzystać i przede wszsytkim poczytaj o OwnerDraw i właściwościach Canvas z jakiegokolwiek kursu;

2

ustawić listBox1.DrawMode na OwnerDrawVariable

        public Form1()
        {
            InitializeComponent();

            listBox1.Items.Add(Bitmap.FromFile(@"c:\a.png"));
            listBox1.Items.Add(Bitmap.FromFile(@"c:\b.png"));
            listBox1.Items.Add(Bitmap.FromFile(@"c:\c.png"));
        }

        private void listBox1_MeasureItem(object sender, MeasureItemEventArgs e)
        {
            Bitmap bmp = ((ListBox)sender).Items[e.Index] as Bitmap;
            e.ItemHeight = bmp.Height;
            e.ItemWidth = bmp.Width;
        }

        private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
        {
            e.DrawBackground();
            Bitmap bmp = ((ListBox)sender).Items[e.Index] as Bitmap;
            e.Graphics.DrawImage(bmp, e.Bounds.Left, e.Bounds.Top);
            e.DrawFocusRectangle();
        }

PS. Następne pytanie będzie brzmiało „a jak teraz dodać tekst”. Postaraj się, dojdź czasem do czegoś samemu…

0

dlaczego rozsmarowuje mi obrazek na cały listbox?

1
maszynaz napisał(a)

dlaczego rozsmarowuje mi obrazek na cały listbox?

Bo pewnie wykorzystujesz kanwę kontrolki, a nie danej pozycji;
Wykorzystaj argument DrawItemEventArgs e tak, jak zrobił to @Azarien;

1

Do zwykłego ListBoxa nie da się dodać obrazka, ale możesz napisać własną klasę dziedziczącą po ListBox i zdefiniować w niej operator.

using System;
using System.Drawing;
using System.Windows.Forms;

namespace ConsoleApplication19
{
    class Program
    {
        static void Main(string[] args)
        {
            MerkuryListBox slb = new MerkuryListBox();
            Image img = new Bitmap(800, 600);

            int wynik = slb + img;
            Console.WriteLine(wynik);
            Console.ReadLine();
        }
    }

    public class MerkuryListBox : ListBox
    {
        public static int operator +(MerkuryListBox listBox, Image image)
        {
            return 666;
        }
    }
}

0
somekind napisał(a)

Do zwykłego ListBoxa nie da się dodać obrazka, ale możesz napisać własną klasę dziedziczącą po ListBox i zdefiniować w niej operator.

A nie ma takiej metody jak AddObject w Pascal'u? Tam można pakować różne obiekty, nie tylko obrazki;


Niestety dodając do listy obrazek jako obiekt jest problem ze zdarzeniem OnMeasureItem - najpierw ustalany jest rozmiar itema w tym zdarzeniu, a dopiero po tym tworzony jest obiekt; Być może w nowszych środowiskach niż D7 jest to inaczej zaplanowane;


Metodę ListBox.AddObject można wykorzystać np. tak:

procedure TForm1.FormCreate(Sender: TObject);
begin
  with lbSquares.Items do
    begin
      AddObject('Square', TBitmap.Create());
      (Objects[Count - 1] as TBitmap).LoadFromFile('Square.bmp');

      AddObject('Square 2', TBitmap.Create());
      (Objects[Count - 1] as TBitmap).LoadFromFile('Square2.bmp');
    end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
  I: Word;
begin
  for I := 0 to lbSquares.Items.Count - 1 do
    lbSquares.Items.Objects[I].Free();
end;

procedure TForm1.lbSquaresDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
  with lbSquares.Canvas do
    begin
      if odSelected in State then
        begin
          Pen.Color := clBlack;
          Brush.Color := clBlack;
        end
      else
        begin
          Pen.Color := clWhite;
          Brush.Color := clWhite;
        end;

      Rectangle(Rect);
      Draw(Rect.Left + 2, Rect.Top + 2, (lbSquares.Items.Objects[Index] as TBitmap));

      if odFocused in State then
        begin
          Pen.Color := Pen.Color xor $FFFFFF;
          DrawFocusRect(Rect);
        end;
    end;
end;

Pliki:

Square.bmp:
Square.png

Square2.bmp:
Square2.png

Efekt wykorzystania powyższego kodu:

Result.png

W załączniku kod programu i plik wykonywalny;

0

Do zwykłego ListBoxa nie da się dodać obrazka
A co ja niby pokazałem, bez dziedziczenia?

A nie ma takiej metody jak AddObject w Pascal'u? Tam można pakować różne obiekty, nie tylko obrazki;
Czy naprawdę nikt nie czyta moich postów?
To mogę przestać pisać…

1 użytkowników online, w tym zalogowanych: 0, gości: 1