PDA

View Full Version : سوال: پاک کردن رکورد از دیتابیس بوسیله چک باکس درون دیتاگرید ویو کامپوننت تلریک



barman.ar16
دوشنبه 07 اسفند 1396, 09:58 صبح
سلام به دوستان و اساتید

توی یه برنامه سی شارپی که بصورت وین فرم دارم مینویسم در تمام قسمت های برنامه از گریدویو تلریک استفاده کردم

من میخوام برای حذف اطلاعات از دیتابیس یک ستون درون گرید ویو تلریک درست کنم که بصورت چک باکسی باشه و بعدش مواردی رو که کاربر تیک میزنه رو بصورت تجمعی از دیتابیس پاک کنم (دنبال این روش هستم روش multiple select بدردم نمیخوره)

توی کار با for مشکلی ندارم دستور پاک کردن یک رکورد از دیتابیس رو هم میدونم ولی اینکه چطوری چک کنم ببینم کدوم رکوردها چک خوردن یا نه رو بلد نیستم خیلی هم جستجو کردم اما تا دلتون بخواد برای دیتاگرید ویو معمولی وجود داره اما متاسفانه برای تلریک پیدا نکردم

ممنون میشم هر کس میدونه راهنمایی کنه ، متشکرم

barman.ar16
دوشنبه 07 اسفند 1396, 20:54 عصر
دوستان من این کد رو برای دیتاگرید ویو خود ویژوال پیدا کردم


List<int> rowsToDelete = new List<int>();
using (SqlConnection conn = new SqlConnection("connString"))
{
using (SqlCommand cmd = new SqlCommand())
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
DataGridViewCheckBoxCell checkBox = dataGridView1[0, row.Index] as DataGridViewCheckBoxCell;
if (checkBox != null)
{
if (Convert.ToBoolean(checkBox.Value) == true)//checking if tick is added
{

cmd.CommandText = @"DELETE FROM Stock WHERE ID = @myID";
cmd.Parameters.Add("@myID", SqlDbType.Int).Value = Convert.ToInt32(dataGridView1[1, row.Index].Value.ToString());
cmd.ExecuteNonQuery();


rowsToDelete.Add(row.Index);
}
}
}
}
}

//حذف از دیتاگرید
foreach (int row in rowsToDelete)
dataGridView1.Rows.RemoveAt(row);





خب چطوری میتونم این رو برای دیتاگریدویو تلریک تغییر بدم
ممنون میشم راهنمایی کنید

رامین مرادی
سه شنبه 08 اسفند 1396, 08:34 صبح
راحت تر از این نمیتونستم بنویسم.:خجالت:



for (int i = 0; i < dgv1.RowCount; i++)
{
if (bool.Parse(dgv1.Rows[i].Cells["نام ستون چک باکس"].Value.ToString()))
{
//کدهای مربوط به حذف از دیتا بیس
}
}



بعد اینکار هم یه بار داده هارو دوباره سلکت کن و بریز تو دیتا گرید تا از دیتاگرید هم حذف بشن

barman.ar16
سه شنبه 08 اسفند 1396, 19:28 عصر
راحت تر از این نمیتونستم بنویسم.:خجالت:



for (int i = 0; i < dgv1.RowCount; i++)
{
if (bool.Parse(dgv1.Rows[i].Cells["نام ستون چک باکس"].Value.ToString()))
{
//کدهای مربوط به حذف از دیتا بیس
}
}



بعد اینکار هم یه بار داده هارو دوباره سلکت کن و بریز تو دیتا گرید تا از دیتاگرید هم حذف بشن

ممنون دوست عزیز

من کدم رو اینطوری نوشتم

SqlConnection connection = new SqlConnection("connectionstring");
string sqlStatement = "DELETE FROM tbl_stbase WHERE melli = @melli";
connection.Open();
SqlCommand cmd = new SqlCommand(sqlStatement, connection);
cmd.Parameters.AddWithValue("@melli", melli);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
loadrgv();


خب این کد مشکلی نداره حالا میمونه اینکه @melli رو از کجا بگیره که من این کد رو زیر for نوشتم :

var melli = rgv.Rows[i].Cells[4].Value;


سلول 4 همون کد ملی هست در جدول ...
خب با این کد در واقعا همه چیز درسته یعنی ما میگیم هر بار که اون دستور if که شما زحمت کشیدید گذاشتید درست بود ملی مورد نظر رو بگیر و عملیات حذف رو انجام بده و این کار رو انجام بده
اما در عمل بعد از پاک کردن ردیف اول exception میده

فکر کنم باید اون کد رو اینطوری بنویسم :

int melli = Int32.Parse(rgv.Rows[i].Cells[4].Value.ToString());


خب اگر اینطوری بنویسم که منطقی تر هم هست چون هر بار میخواد توی حلقه for قرار بگیره و اینکار رو انجام بده باید از نوع اینتجر باشه (البته این طرز فکر من هست نمیدونم درسته یا نه)
دوباره exception میده اگر از نوع استرینگ بگیرم باز هم exception میده

موندم چکار کنم ... راستش به این روش خیلی نیاز دارم چون میخوام برای چاپ هم همین متد رو استفاده کنم و اون مورادی رو که تیک خوردن رو بفرستم برای چاپ که اگر این نشه حتما اون هم نمیشه

آخرین مورد اینکه نوع ستون کد ملی رو درون sql از نوع nvarchar(50) گرفتم نمیدونم به اون ربطی داره یا نه

ممنون

mr.sirwan
سه شنبه 08 اسفند 1396, 19:54 عصر
اول از همه خطا رو اینجا قرار بدین که بدونیم خطا چیه اینجوری که نمیشه نظر داد، دوما شما وقتی فیلدت از نوع nvarchar چرا مقدار melli رو تبدیل به int میکنی؟؟ :اشتباه: و دوباره وقتی فیلدت از نوع nvarchar باشه باید توی کوئری مقدار اون فیلد رو داخل سینگل کوت (') قرار بدی که شما اینکارو نکردی

در ضمن چون تازه شروع کردی به برنامه نویسی این نکته رو بگم، هر وقت از کانکشن استفاده کردی، آخرسر اون رو ببند تا رم رو الکی اشغال نکنه حالا یا داخل بلاک using از sqlconnection استفاده کن، یا خودت دستی متد close و dispose مربوط به ابجکت sqlconnection رو به ترتیب قراخوانی کن

barman.ar16
سه شنبه 08 اسفند 1396, 21:18 عصر
اول از همه خطا رو اینجا قرار بدین که بدونیم خطا چیه اینجوری که نمیشه نظر داد، دوما شما وقتی فیلدت از نوع nvarchar چرا مقدار melli رو تبدیل به int میکنی؟؟ :اشتباه: و دوباره وقتی فیلدت از نوع nvarchar باشه باید توی کوئری مقدار اون فیلد رو داخل سینگل کوت (') قرار بدی که شما اینکارو نکردی

در ضمن چون تازه شروع کردی به برنامه نویسی این نکته رو بگم، هر وقت از کانکشن استفاده کردی، آخرسر اون رو ببند تا رم رو الکی اشغال نکنه حالا یا داخل بلاک using از sqlconnection استفاده کن، یا خودت دستی متد close و dispose مربوط به ابجکت sqlconnection رو به ترتیب قراخوانی کن

ممنون از توضیحاتتون استفاده می کنم

در خصوص اون کدی که جهت حذف از دیتابیس گذاشتم فقط جهت نوشتن نحوه کار بود در صورتیکه من دارم به روش entity framework کار می کنم
خب در نهایت با این کد مشکلم حل شد :


for (var i = 0; i < rgv.RowCount; i++)
{
var melli = rgv.Rows[i].Cells[4].Value;
string id = melli.ToString();
if (!Convert.ToBoolean(rgv.Rows[i].Cells[0].Value)) continue;
tbl_stbase tbl_stbase = database.tbl_stbase.First(j => j.melli == id && j.year == lblyear.Text);
database.tbl_stbase.Remove(tbl_stbase);
database.SaveChanges();

}
loadrgv();


الان فقط یه چیز دیگه مونده اون هم اینکه من چطوری اولش چک کنم ببینم ردیفی تیک خورده یا نه تا اگر تیک خورده بود با یک پیغام yes یا no اجازه پاک کردن یا نکردن داده ها رو بدم یا نه؟ اگر yes رو زد اون حلقه رو به کار ببرم اگر هم no کلیک شد تیک ها رو بردارم و از اول همه چیز قرار بگیره
اگر هم تیکی اصلا زده نشده بود پیغام بدم اول ردیفی رو تیک بزنید بعد پاک کنید

ممنون از دوستانی که زحمت می کشند و راهنمایی می کنند

mr.sirwan
سه شنبه 08 اسفند 1396, 21:59 عصر
دوتا راه داری، اول اینکه قبل از عمل حذف یک بار حلقه for رو اجرا کنی و به محض اینکه به اولین سطر تیک خورده رسیدی حلقه رو متوقف کنی و حالا پیغام مناسب رو به کاربر نشون بدی تا yes یا no رو کلیک کنه که این روش درصورتیکه تعداد سطرهات زیاد باشه سرعت افت پیدا میکنه

اما روش دوم اینه که یه لیست از نوع int تعریف کنی و هربار که سطری تیک میخوره یا تیکش برداشته میشه، همون موقع اندیس اون سطر رو به لیست اضافه یا از لیست حذف کنی، در این حالت واسه فهمیدن اینکه سطری تیک خورده یا نه فقط کافیه چک کنی که لیستت عنصری داره یا خیر؟ اگر هیچ عنصری توی لیست نبود یعنی هیچ سطری تیک نخورده، اگرم بود که پیغام مناسب رو به کاربر نشون بده تا yes و no رو انتخاب کنه و بقیه ماجرا..... برای حذف از دیتابیس هم میتونی به جای حلقه for ی که کل سطر هارو پیمایش میکنه، فقط همین لیست رو پیمایش کنی که حاوی اندیس سطر های تیک خورده س و سرعت هم به طبع بیشتر از روش اول خواهد بود

barman.ar16
پنج شنبه 10 اسفند 1396, 21:11 عصر
دوتا راه داری، اول اینکه قبل از عمل حذف یک بار حلقه for رو اجرا کنی و به محض اینکه به اولین سطر تیک خورده رسیدی حلقه رو متوقف کنی و حالا پیغام مناسب رو به کاربر نشون بدی تا yes یا no رو کلیک کنه که این روش درصورتیکه تعداد سطرهات زیاد باشه سرعت افت پیدا میکنه

اما روش دوم اینه که یه لیست از نوع int تعریف کنی و هربار که سطری تیک میخوره یا تیکش برداشته میشه، همون موقع اندیس اون سطر رو به لیست اضافه یا از لیست حذف کنی، در این حالت واسه فهمیدن اینکه سطری تیک خورده یا نه فقط کافیه چک کنی که لیستت عنصری داره یا خیر؟ اگر هیچ عنصری توی لیست نبود یعنی هیچ سطری تیک نخورده، اگرم بود که پیغام مناسب رو به کاربر نشون بده تا yes و no رو انتخاب کنه و بقیه ماجرا..... برای حذف از دیتابیس هم میتونی به جای حلقه for ی که کل سطر هارو پیمایش میکنه، فقط همین لیست رو پیمایش کنی که حاوی اندیس سطر های تیک خورده س و سرعت هم به طبع بیشتر از روش اول خواهد بود

ممنون
روش ساخت لیست و اضافه کردن عضو به لیست رو بلدم ولی هر کار میکنم نمیدونم چطوری ردیف هایی که تیک میخورند رو به لیست اضافه کنم
به نظرم باید توی یک event مناسب از event های گرید ویو تلریک اینکار رو انجام بدم درسته ...
اگر کسی میتونه راهنمایی کنه ممنون میشم توی کدنویسیش کمک کنه

دقیقا مشابه به همین قضیه جهت ارسال ردیف های تیک خورده به چاپ هم میخوام استفاده کنم که گیر این موضوع هستم
متشکرم

danialafshari
پنج شنبه 10 اسفند 1396, 22:41 عصر
ممنون
روش ساخت لیست و اضافه کردن عضو به لیست رو بلدم ولی هر کار میکنم نمیدونم چطوری ردیف هایی که تیک میخورند رو به لیست اضافه کنم
به نظرم باید توی یک event مناسب از event های گرید ویو تلریک اینکار رو انجام بدم درسته ...
اگر کسی میتونه راهنمایی کنه ممنون میشم توی کدنویسیش کمک کنه

دقیقا مشابه به همین قضیه جهت ارسال ردیف های تیک خورده به چاپ هم میخوام استفاده کنم که گیر این موضوع هستم
متشکرم
با سلام
شما بعد از چک کردن اینکه تیک خورده توسط کد زیر ID رو به لیست بفرست

List<int> IDList = new List<int>();
private void AddList()
{
int rowindex = Convert.ToInt32(dataGridView1[0, dataGridView1.CurrentRow.Index].Value);


if (dataGridView1.RowCount == 0)
{
MessageBox.Show("اطلاعاتی وجود ندارد");
}
else
{
if (IsExist(rowindex))
MessageBox.Show("تکراری است");
else
IDList.Add(rowindex);
}
}


private bool IsExist(int rowIndex)
{
int result = IDList.FirstOrDefault(s => s == rowIndex);
return Convert.ToBoolean(result);
}

در مثال بالا ID در اندیس 0 است
و توسط کد پایین هم میتونی محتویات لیست رو به دیتابیس اضافه کنی

if (IDList.Count == 0)
{
MessageBox.Show("چیزی انتخاب نشده است");
return;
}
foreach (var item in IDList)
{
//Insert Into item to Database
}
IDList.Clear();

موفق باشید

mr.sirwan
پنج شنبه 10 اسفند 1396, 22:46 عصر
با سلام
شما بعد از چک کردن اینکه تیک خورده توسط کد زیر ID رو به لیست بفرست


البته منظورشون این بود که با چه ایونتی تیک خوردن چک باکس رو تشخیص بدن، بنده تاحالا با تلریک کار نکردم نمیتونم در این مورد نظری بدم

danialafshari
پنج شنبه 10 اسفند 1396, 22:59 عصر
البته منظورشون این بود که با چه ایونتی تیک خوردن چک باکس رو تشخیص بدن، بنده تاحالا با تلریک کار نکردم نمیتونم در این مورد نظری بدم
باید ValueChanged باشه

void radGridView1_ValueChanged(object sender, EventArgs e)
{
if (this.radGridView1.ActiveEditor is RadCheckBoxEditor)
{
Console.WriteLine(this.radGridView1.CurrentCell.Ro wIndex);
Console.WriteLine(this.radGridView1.ActiveEditor.V alue);
}
}

https://docs.telerik.com/devtools/winforms/gridview/columns/column-types/gridviewcheckboxcolumn

barman.ar16
جمعه 11 اسفند 1396, 21:51 عصر
دوستان هر کاری کردم نشد که نشد !!!! ....

اون طوری که استاد عزیز danialafshari (http://barnamenevis.org/member.php?68467-danialafshari) اشاره کردند که اصلا کاری نشد انجام بدم فکر می کنم به درد دیتا گرید ویو استاندارد میخوره اما برای گرید ویو تلریک کاربرد نداره من هم سعی کردم تغییرش بدم برای تلریک نشد که نشد
در مورد پست آخر هم که اصلا نفهمیدم دقیقا چه اتفاقی داره میفته !!!!

در کل اگر من بتونم اول چک کنم که آیا ردیفی تیک خورده یا نه با پیغام هشدار مبنی بر اول ردیفی رو انتخاب کنید یا به روش فعال یا غیرفعال کردن دکمه حذف اطلاعات کار رو پیش میبرم (که دوست عزیز mr.sirwan (http://barnamenevis.org/member.php?369257-mr-sirwan) روش ساخت لیست و اضافه کردن ردیف تیک خورده به اون رو پیشنهاد دادن که بسیار منطقی هم به نظر میرسه ولی اینکه چطوری اینکار رو بکنم هر کاری کردم نشد البته روش هایی رو پیدا کردم ولی به درد گرید ویو تلریک نمی خوردند )

بعد هم بوسیله یک پیغام هشدار مبنی بر اینکه آیا از حذف ردیف های تیک خورده اطمینان دارید کار رو جلو می برم
اگر no کلیک شد با دستور :

dataGridViewC1.EndEdit();

تیک ها رو برمیدارم
و اگر هم yes کلیک شد بوسیله این حلقه for ردیف های تیک خورده رو پاک می کنم :

for (var i = 0; i < rgv.RowCount; i++)
{
var melli = rgv.Rows[i].Cells[4].Value;
string id = melli.ToString();
if (!Convert.ToBoolean(rgv.Rows[i].Cells[0].Value)) continue;
tbl_stbase tbl_stbase = database.tbl_stbase.First(j => j.melli == id && j.year == lblyear.Text);
database.tbl_stbase.Remove(tbl_stbase);
database.SaveChanges();

}
loadrgv();





الان مشکل میمونه چک کردن اینکه آیا ردیفی تیک خورده یا نه ؟؟؟!!!
ممنون میشم دوستان و اساتید عزیز راهنمایی کنند ، متشکرم

mr.sirwan
جمعه 11 اسفند 1396, 22:15 عصر
یه سر به این لینکا بزن ببین کدوم به کارت میاد:

https://stackoverflow.com/questions/11843488/how-to-detect-datagridview-checkbox-event-change
https://social.msdn.microsoft.com/Forums/windows/en-US/a52ce950-c579-415e-bfad-07770d71fc00/datagridviewcheckboxcolumn-check-changed?forum=winformsdatacontrols
https://stackoverflow.com/questions/22284280/datagridview-event-for-checked-change

danialafshari
جمعه 11 اسفند 1396, 23:59 عصر
با سلام
روشی که در پست اول گفتم ربطی به تلریک نداشت کار با لیست هست تقریباً همه ی حالاتش رو در نظر گرفتم فقط وقتی که تیک رو برمیداره (طبق پست 2) که زحمتشو خودتون بکشید البته اگر کدها رو دقیق ببینید یک اشاره ای هم شده
در پست اول 2 بار اسم DataGridView اورده و اولیش بدست آوردن Value هست و دومیش تابع Count بود که تعداد رکوردها رو برمیگردونه طبق تلریک توسط کد زیر Value رو بدست بیارید

dgv1.Rows[i].Cells["نام ستون چک باکس"].Value.ToString()

و اگر لیست خالی باشه یعنی رکوردی رو انتخاب نکرده
در پست دوم هم از فروم تلریک هست و خودم ندارم براتون تست کنم و به نظر درست میاد
موفق باشید

ژیار رحیمی
شنبه 12 اسفند 1396, 03:12 صبح
سلام.
برای حذف تکی (به محض چک دار کردن رکورد در دیتابیس و دیتاگرید حذف شود) .نام ستون از نوع چکباکس در دیتاگرید check ونام ستون آیدی رکورذ Id میباشد


private void radGridView1_CellEndEdit(object sender, GridViewCellEventArgs e)
{
if (e.ColumnIndex == radGridView1.Columns["check"].Index && e.RowIndex != -1)
{
if ((bool)radGridView1.CurrentRow.Cells["check"].Value)
{
using (SqlCommand cmd = new SqlCommand())
{
var myID= (int)radGridView1.CurrentRow.Cells["Id"].Value;
cmd.CommandText = @"DELETE FROM Stock WHERE ID = @myID";
cmd.Parameters.Add("@myID", SqlDbType.Int).Value = myID);
cmd.ExecuteNonQuery();
//حذف سطر جاری در دیتاگرید
radGridView1.Rows[e.RowIndex].Delete();
}
}

}
}




اگر هم بخوای بصورت گروهی حذف شود باید یه لیست برای نگهداری رکوردهای انتخاب شده در نظر بگیری . ابتدا یک کلاس کمکی برای نگهداری RowIndexو RecordId رکورد انتخاب شد تعریف شود

public class Rec
{
public int RowInex { get; set; }
public int RecordId { get; set; }
}

نحوه اضافه کردن ایتم انتخاب شده به لیست رکوردهای انتخابی بصورت زیر عمل شود

List<Rec> SelectedItems = new List<Rec>();
private void radGridView1_CellEndEdit(object sender, GridViewCellEventArgs e)
{
if (e.ColumnIndex == radGridView1.Columns["check"].Index && e.RowIndex != -1)
{
if ((bool)radGridView1.CurrentRow.Cells["check"].Value)
SelectedItems.Add(new Rec { RowInex = e.RowIndex, RecordId = (int)radGridView1.CurrentRow.Cells["Id"].Value });
else
SelectedItems.Remove(SelectedItems.Find(c => c.RowInex == e.RowIndex));

}
}


حالا شما لیستی از Id رکورد های نتخاب شده در دیتاگرید را دارید با حلقه foreach تک تک Id ها حذف شود

foreach (var item in SelectedItems)
{
using (SqlCommand cmd = new SqlCommand())
{

cmd.CommandText = @"DELETE FROM Stock WHERE ID = @myID";
cmd.Parameters.Add("@myID", SqlDbType.Int).Value = item.RecordId);
cmd.ExecuteNonQuery();
radGridView1.Rows[item.RowInex].Delete();
}
}