به درستی اشاره کردن، رخداد SelectionChanged ئه. و البته در اغلب موارد CurrentRow مشخصه مناسب نیست، باید بجاش از dataGridView1.SelectedRows[0] استفاده بشه. CurrentRow آخرین سطری رو مشخص میکنه که عملیاتی رویش انجام شده، مثلا انتخاب شده یا از حالت انتخاب در اومده و ... برای همین ممکنه به سطری اشاره کنه که دیگه در حالت انتخاب شده نیست. به ندرت مواردی پیدا میشه که CurrentRow انتخاب مناسبی باشه.
در ضمن معمولا در DataGridView یا ListView و ... علاوه بر نمایش داده عملیات هایی مثل حذف و ویرایش و ... هم داریم و نیازه به مقادیر داخل سطر ها رجوع بشه.
لذا اگر برای داده هاتون یک کلاس یا ساختار (struct) تعریف کرده اید، بهتره که از اشیاء همون کلاس یا ساختار در DataGridView تون استفاده کنید تا مجبور نشید برای دسترسی به تصویر مربوط به فلان سطر با textBox و ... درگیر بشید.
مثلا فرض کنیم یک کلاس مثل Person داریم که قراره در DataGridView نمایش داده بشه :
using System.Globalization;
using System.IO;
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhotoId { get; set; }
public DateTime Date { get; set; }
public string PhotoPath => Path.Combine(Environment.CurrentDirectory, "Photos" + PhotoId + ".jpg");
public Person(string firstName, string lastName, string photoId, DateTime date)
{
FirstName = firstName;
LastName = lastName;
PhotoId = photoId;
Date = date;
}
}
می توانیم برای این کلاس Format تعریف کنیم تا DataGridView بتونه یک شیء از این کلاس رو بصورت های متفاوتی نشون بده :
using System.Globalization;
using System.IO;
public class Person : IFormattable
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string PhotoId { get; set; }
public DateTime Date { get; set; }
public string PhotoPath => Path.Combine(Environment.CurrentDirectory, "Photos" + PhotoId + ".jpg");
public Person(string firstName, string lastName, string photoId, DateTime date)
{
FirstName = firstName;
LastName = lastName;
PhotoId = photoId;
Date = date;
}
public string ToString(string format, IFormatProvider formatProvider)
{
switch (format.ToLower())
{
case "firstname":
return FirstName;
case "lastname":
return LastName;
case "photoid":
return PhotoId;
case "date":
var persian = new PersianCalendar();
return $"{persian.GetYear(Date):0000}/{persian.GetMonth(Date):00}/{persian.GetDayOfMonth(Date):00}";
default:
return string.Empty;
}
}
}
و در هر کدوم از ستون های DataGridView مشخص کنیم که چه فیلدی رو نمایش بده، مثلا lastname برای ستونی که قراره نام خانوادگی رو نشون بده و date برای ستونی که تاریخ رو نشون میده :
preview1.png
و موقع درج سطر در DataGridView همه ستون ها همون شیء Person هستند، نه مقدار یک فیلد که بعدا ربط دادنش به شیء داده مون دشوار میشد :
private void button1_Click(object sender, EventArgs e)
{
var persian = new PersianCalendar();
var item = new Person("محسن", "غلامی", "6106", new DateTime(1380, 11, 8, persian));
dataGridView1.Rows.Add(item, item, item, item);
}
و هر زمان بخواهیم فرضا PhotoPath رو دریافت کنیم، شیء person در همه ستون ها قرار داره :
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count == 0)
{
return;
}
try
{
var person = (Person)dataGridView1.SelectedRows[0].Cells[0].Value;
pictureBox1.BackgroundImageLayout = ImageLayout.Zoom;
pictureBox1.BackgroundImage = Image.FromFile(person.PhotoPath);
}
catch
{
pictureBox1.BackgroundImage = null;
}
}