I'm having problems with the image location in listbox. I want to show an image under the text, but the image appears over the text. Can you help me with this?
private void listBoxQuestions_MeasureItem(object sender, MeasureItemEventArgs e) { ComboBoxItem item = listBoxQuestions.Items[e.Index] as ComboBoxItem; if (item != null) { string questionText = item.Text; using (Graphics g = e.Graphics) { // ListBox'in mevcut genisligine göre metnin sigmasini saglamak için ölçüm yapiyoruz int itemWidth = listBoxQuestions.Width - 30; // Kenarlik payi için biraz bosluk birakiyoruz SizeF textSize = g.MeasureString(questionText, listBoxQuestions.Font, itemWidth); // Yüksekligi, ölçülen metin yüksekligine göre dinamik olarak ayarliyoruz e.ItemHeight = (int)Math.Max(30, textSize.Height + 2); // Minimum 30px, metnin boyutuna göre artiriyoruz } } } private void listBoxQuestions_DrawItem(object sender, DrawItemEventArgs e) { if (e.Index < 0) return; // ListBox'taki ögeler arasinda gezinip ComboBoxItem'lari kontrol ediyoruz if (listBoxQuestions.Items[e.Index] is ComboBoxItem item) { // Baslik olan item'lar için seçilebilirligi kontrol ediyoruz if (!item.Selectable) { // Kazanim adi (Ilgili Kazanim) için mavi ve bold font kullaniliyor if (item.Text.StartsWith("Ilgili Kazanim")) { e.Graphics.FillRectangle(Brushes.White, e.Bounds); // Arka plan rengi e.Graphics.DrawString(item.Text, new System.Drawing.Font(e.Font, FontStyle.Bold), Brushes.Blue, e.Bounds); // Kazanim adi yazi rengi ve font stili } else if (item.Text.StartsWith("--")) // Baslik metnini kontrol ediyoruz { e.Graphics.FillRectangle(Brushes.White, e.Bounds); // Arka plan rengi e.Graphics.DrawString(item.Text, new System.Drawing.Font(e.Font, FontStyle.Bold), Brushes.Black, e.Bounds); // Baslik yazi rengi ve font stili } else { e.Graphics.FillRectangle(Brushes.White, e.Bounds); // Arka plan rengi e.Graphics.DrawString(item.Text, e.Font, Brushes.Black, e.Bounds); // Diger ögeler için siyah yazi rengi } } else { // Normal ögeler için çizim islemi e.DrawBackground(); // Baska bir seçim durumu varsa arka plani çiz // Checkbox alani System.Drawing.Rectangle checkboxRect = new System.Drawing.Rectangle(e.Bounds.Left + 5, e.Bounds.Top + 5, 12, 12); e.Graphics.FillRectangle(Brushes.White, checkboxRect); e.Graphics.DrawRectangle(Pens.Black, checkboxRect); // Eger isaretliyse, bir tik isareti çiz if (item.IsChecked) { e.Graphics.DrawString("?", e.Font, Brushes.Black, checkboxRect.Left + 1, checkboxRect.Top + 1); } // **Resmin Gösterimi** string imagePath = item.Value as string; if (!string.IsNullOrEmpty(imagePath) && File.Exists(imagePath)) { try { // Resmi yükle ve uygun boyutlara getir Image img = Image.FromFile(imagePath); // Resmi, metnin sol tarafina ekle int imageWidth = 40; int imageHeight = (int)((float)img.Height / img.Width * imageWidth); // Resmi orantili sekilde boyutlandir // Resmi çizin e.Graphics.DrawImage(img, e.Bounds.Left + 20, e.Bounds.Top + 5, imageWidth, imageHeight); } catch (Exception ex) { // Resim yükleme hatasi MessageBox.Show("Resim yüklenemedi: " + ex.Message); } } // **Metni Gösterme** // Sorunun metnini checkbox'in saginda çiziyoruz e.Graphics.DrawString(item.Text, e.Font, Brushes.Black, e.Bounds.Left + 30, e.Bounds.Top + 5); // Metni resmin saginda çiz } } e.DrawFocusRectangle(); // Seçim vurgusunu çizer } public void LoadQuestions(List<int> selectedRids) { // Öncelikle listBoxQuestions içindeki tüm kontrolleri (resimler gibi) temizleyelim foreach (Control control in listBoxQuestions.Controls) { if (control is PictureBox pictureBox) { listBoxQuestions.Controls.Remove(pictureBox); // Resmi kaldir pictureBox.Dispose(); // Bellekten temizle } } listBoxQuestions.Items.Clear(); // Listeyi temizle string previousTitle = ""; // Basliklari karsilastirmak için string previousAdditionalText = ""; // Ayni açiklama metninin tekrar eklenmesini engellemek için string previousKazanimAdi = ""; // Kazanim adinin tekrarlanmamasi için using (SQLiteConnection connection = new SQLiteConnection(connectionString)) { connection.Open(); foreach (int kid in selectedRids) { SQLiteCommand cmd = new SQLiteCommand( "SELECT sorular.soru, sorutip.baslik, sorumetni.metin, sorumetni.resim_yolu, kazanimlar.kadi FROM sorular " + "LEFT JOIN sorutip ON sorular.tid = sorutip.tid " + "LEFT JOIN sorumetni ON sorular.sid = sorumetni.sid " + "LEFT JOIN kazanimlar ON sorumetni.kid = kazanimlar.kid " + "WHERE sorumetni.kid = @kid ORDER BY sorutip.baslik", connection); cmd.Parameters.AddWithValue("@kid", kid); SQLiteDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { string questionTitle = reader["baslik"].ToString(); string additionalText = reader["metin"] != DBNull.Value ? reader["metin"].ToString() : ""; string questionText = reader["soru"].ToString(); string imagePath = reader["resim_yolu"] != DBNull.Value ? reader["resim_yolu"].ToString() : ""; // Kazanim adi kontrolü string kazanimAdi = reader["kadi"] != DBNull.Value ? reader["kadi"].ToString() : "Bilinmiyor"; // Eger "kadi" null ise "Bilinmiyor" yazsin. // Basliklari ekliyoruz, ancak bunlara checkbox eklemiyoruz if (questionTitle != previousTitle) { // Kazanim adi daha önce eklenmediyse ekliyoruz if (kazanimAdi != previousKazanimAdi) { if (!string.IsNullOrEmpty(previousKazanimAdi)) { // Önceki kazanim eklenmisse, araya bos satir ekliyoruz listBoxQuestions.Items.Add(new ComboBoxItem { Text = "", // Bos satir Value = "", Selectable = false, // Seçilemez IsChecked = false // Checkbox'li degil }); } listBoxQuestions.Items.Add(new ComboBoxItem { Text = $"Ilgili Kazanim : {kazanimAdi}", // Kazanim adi Value = "", Selectable = false, // Seçilemez IsChecked = false // Checkbox'li degil }); previousKazanimAdi = kazanimAdi; // Kazanim adini kaydediyoruz } // Baslik metnini ekliyoruz listBoxQuestions.Items.Add(new ComboBoxItem { Text = $"-- {questionTitle}", // Baslik Value = "", Selectable = false, // Basliklar seçilemez IsChecked = false // Basliklar checkbox'li degil }); previousTitle = questionTitle; previousAdditionalText = ""; // Baslik degistiginde açiklamayi sifirla } // Eger açiklama metni varsa ve daha önce eklenmemisse, onu da alt baslik olarak ekliyoruz if (!string.IsNullOrEmpty(additionalText) && additionalText != previousAdditionalText) { listBoxQuestions.Items.Add(new ComboBoxItem { Text = additionalText, Value = additionalText, Selectable = false, // Açiklamalar seçilemez IsChecked = false // Checkbox'li degil }); previousAdditionalText = additionalText; // Eklenen açiklamayi kaydediyoruz } // Resim ekleme string baseDirectory = AppDomain.CurrentDomain.BaseDirectory; // Dinamik çalisma dizini string imageDirectory = Path.Combine(baseDirectory, "resimler"); // Resim klasörü string imageFileName = reader["resim_yolu"].ToString(); // Veritabanindan gelen dosya adi string resim = Path.Combine(imageDirectory, imageFileName); // Tam dosya yolu olustur if (!string.IsNullOrEmpty(resim) && File.Exists(resim)) { // Resim için PictureBox olusturuluyor PictureBox pictureBox = new PictureBox { Image = Image.FromFile(resim), SizeMode = PictureBoxSizeMode.StretchImage, Height = 100, // Resim yüksekligi Width = 100, // Resim genisligi Margin = new Padding(5) }; // Resmi listeye ekliyoruz (listBox yerine FlowLayoutPanel veya benzeri bir kontrol kullanilabilir) listBoxQuestions.Controls.Add(pictureBox); } else { Console.WriteLine("Resim bulunamadi: " + resim); // Resim bulunamadiginda hata mesaji } // Sorulari checkbox'li ekliyoruz, ancak soru bossa checkbox eklemiyoruz if (!string.IsNullOrEmpty(questionText)) // Eger soru metni bos degilse { listBoxQuestions.Items.Add(new ComboBoxItem { Text = questionText, Value = questionText, Selectable = true, // Sorular seçilebilir IsChecked = false // Baslangiçta checkbox isaretli degil }); } } reader.Close(); } } }