با سلام خدمت استاد باقرزاده ی عزیز؛
فرمی دارم که در اون سه متغییر دریافت میشه و در دیتابیس ذخیره میشه.
قصد دارم یک validator درست کنم که هر سه متغییر رو دریافت کنه و به عبارتی کل فرم رو اعتبار سنجی کنه و در صورتی که اطلاعات وارد شده در دیتابیس وجود داشته باشه، خطا ایجاد کنه.
میشه راهنمایی بفرمایید لطفا؟
با سپاس فراوان
سلام
روش های مختلفی برای اعتبار سنجی وجود دارد:
1 - می توانید سه کلاس با ارث بری از RoleValidation برای ورودی هایتون Bind کنید و هر کدام را جداگانه در دیتابیس تست کنید.
2 - می توانید دکمه ثبت رو با Command پیاده سازی کنید و در رویداد CanExcute ، وضعیت دکمه ثبت را زمانی فعال کنید که مقدار سه ورودی شما در دیتابیس چک شده باشد و در صورت صحیح بودن دکمه فعال شود.
3 - یا می توانید به صورت معمولی زمان ثبت قبل از ذخیره کردن اطلاعات در دیتابیس اعتبار سنجی خود را در رویداد Click دکمه ثبت انجام دهید و در صورت نامعتبر بودن یک MessageBox نمایش دهید تا زمانی که اطلاعات اصلاح شود.
استاد بابت پاسخ سپاسگزارم؛
باید بگم که این سه مقدار که از فرم گرفته می شوند، عملا یک چیز واحد رو پیکر بندی می کنند.
1) نوع مواد 2) گرید مواد 3) کد مواد
نباید در دیتابیس هیچ رکوردی پیدا بشه که نوع، گرید و کدش با مقادیری که کاربر وارد میکنه برابر باشد. پس به نظر من نمیشه به صورت جداگانه بررسی کرد.
من در CodeBehind فرم یک نمونه از اون entity رو ساختم و به DataContext دادم.
public Materials Material = new Materials();
آیا میشه از این Material برای اعتبار سنجی استفاده کرد؟ دسترسی در کلاس Validation به چه صورت خواهد بود؟
سپاس فراوان
شما میتونید یک نمونه از Context در کلاس اعتبار سنجی بسازید و از دیتابیس بررسی معتبر بودن یا نبودن را اعلام کنید.
استاد سلام؛
این کدی هست که در کلاس اعتبار سنجی زدم. اما کار نمیکنه!
public class MaterialValidation : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
if (!string.IsNullOrEmpty(value?.ToString()))
{
wMaterialsAddEdit materialsAddEdit = new wMaterialsAddEdit();
Materials Material = materialsAddEdit.Material;
using (UnitOfWork db = new UnitOfWork())
{
if (!db.MaterialsRepository.GetAll(c => c.MaterialGrade == Material.MaterialGrade
& c.MaterialCode == Material.MaterialCode
& c.MaterialTypeID == Material.MaterialTypeID).Any())
{
return ValidationResult.ValidResult;
}
else
{
return new ValidationResult(false, "این مواد قبلا ثبت شده است.");
}
}
}
else
{
return new ValidationResult(false, "این فیلد نباید خالی باشد.");
}
}
}
با اجازه از استاد
من کاری رو که میکنم براتون میزارم بینید اگه جوابتون رو میده استفاده کنید
///////////کلید ذخیره
private void btnEdit_Click(object sender, RoutedEventArgs e)
{
//کنترل خالی نبودن مقادیر
if (!CheckNullable())
{
return;
}
//دریافت نوع ورودی فرم
switch (Win_type)
{
case 1://اگر یک بود - جدید
{
////فراخوانی متد کنترل تکراری نبودن
if (!CheckdDataBase())
{
return;
}
//فراخانی متد ذخیره
Save();
break;
}
case 2://اگر 2 بود - ویرایش
{
//ElMotortipPS == txtElMotor.Text.Trim()
if (1 == 1)
{
//فراخانی متد ویرایش
Update();
}
else
{
////فراخوانی متد کنترل تکراری نبودن
if (!CheckdDataBase())
{
return;
}
//فراخانی متد ویرایش
Update();
}
break;
}
}
}
////متد ذخیره
private void Save()
{
try
{ //کپی از اکسل >>>>>>>>>>>>>>>ذخیره
MessageBox.Show($" {NameForm} : " + "\n" +
"با موفقیت ذخیره شد",
$"ذخیره {NameForm} ",
MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.OK, MessageBoxOptions.RightAlign | MessageBoxOptions.RtlReading);
this.Close();
}
catch (Exception ex)
{
MessageBox.Show("هنگام ذخیره اطلاعات در دیتابیس مشکلی بوجود آماده لطفاً دوباره سعی کنید" + ex.ToString(), "خطای ارتباطی");
}
finally
{
}
}
////متد ویرایش
private void Update()
{
try
{ //کپی از اکسل >>>>>>>>>>>>>>>ویرایش
MessageBox.Show($" {NameForm} : " + "\n" +
"با موفقیت ویرایش شد",
$"ویرایش {NameForm} ",
MessageBoxButton.OK, MessageBoxImage.None, MessageBoxResult.OK, MessageBoxOptions.RightAlign | MessageBoxOptions.RtlReading);
this.Close();
}
catch (Exception ex)
{
MessageBox.Show("هنگام ویرایش اطلاعات در دیتابیس مشکلی بوجود آماده لطفاً دوباره سعی کنید" + ex.ToString(), "خطای ارتباطی");
}
finally
{
}
}
////فراخوانی متد کنترل تکراری نبودن
private bool CheckdDataBase()
{
try
//اگه خطایی نبود
{
var query = DbVahdat.Database.SqlQuery<tblElMotor>("SELECT * FROM tblElMotor Where 1 = N'" + "1" + "' ");
var result = query.ToList();
if (result.Count > 0)
{
MessageBox.Show($" {NameForm} : " + "\n" +
"از قبل تعریف شده", "اصلاح شود",
MessageBoxButton.OK, MessageBoxImage.Stop, MessageBoxResult.OK, MessageBoxOptions.RightAlign | MessageBoxOptions.RtlReading);
//txtElMotor.Focus();
return false;
}
}
//درصورت وجود خطا
catch (Exception ex)
{
MessageBox.Show("در کنترل دیتابیس مشکلی بوجود آماده لطفاً دوباره سعی کنید" + ex.ToString(), "خطای ارتباطی");
return false;
}
//در هر صورتی اجرا شود
finally
{
}
return true;
///////////////////////////////////////////////////////////////////////کنترل ورودی ها
/////////کنترل خالی نبودن مقادیر
private bool CheckNullable()
{
return true;
}
یه کلید ذخیره دارم وقتی که فرم ادیت رو باز میکنم با یه متغیر که از فرم اول میفرستم که معلوم بشه برای جدید باز شده یا ویرایش اطلاعات
یه توهر دوحالت اولا پر بودن یا درست بودن مقادیر رو چک میکنم
بعد با تابع چک ، اگه قرار باشه چکبشه که تکراری نباشه یا هرچیزی بان چک میکنم
اگه هر دوتا تابع truo بودن ذخیره یا ویرایش انجام
برادر یا خواهر عزیز! (vahdatkaneh)
من می خوام این کا رو با اعتبار سنجی انجام بدم. (ValidationRule)
کاری که شما انجام دادید در رویداد یک دکمه هست که روش های بهتری برای انجام دادن آن وجود داره. به هر حال از پاسخ شما سپاسگزارم.
تیکه زیر رو متوجه نشدم ، لطفا توضیح بدید:
wMaterialsAddEdit materialsAddEdit = new wMaterialsAddEdit();
Materials Material = materialsAddEdit.Material;
و سوال بعد اینکه چرا از value داخل بررسی شرط خودتون استفاده نکردید؟
استاد شرمنده، اشتباهی دستم به «پاسخ صحیح خورد»!!!
اون تیکه کد مربوط به مقادیری هست که در فرم وارد شده. خواستم با این روش اون اطلاعات رو بگیرم و از دیتا بیس کنترل کنم.
value فقط مقدار ورودی اون فیلد رو بر میگردونه، من می خوام تمام فیلد ها رو بررسی کنم.
رکوردی که در DataBase ذخیره میشه نباید تکراری باشه!
سپاس استاد، اط لطف شما سپاسگزارم
شما در این روش نمی تونید با نمونه سازی از کلاس به مقدارش دسترسی داشته باشید به این دلیل که یک نمونه جدید می سازید و مقداری داخلش وجود نداره.
فقط از value می تونید استفاده کنید و برای دسترسی به هر سه مقدار می بایست این اعتبار سنجی را برای هر سه انجام دهید. میتونید سه تا Property در داخل کلاس اعتبارسنجی قرار بدید که توسط Element Binding در سمت XAML پر می شود.
آیا یک فیلد در سمت xaml می تونه به دو پراپرتی bind بشه؟
منظورم اینه که از یک طرف باید به یک نمونه از Entity متصل بشه و از طرف دیگه به Property ای که در اعتبار سنجی استفاده شده؟
یک المنت سمت XAML میتونه فقط به یک Property و صل بشه ولی شما میتونید یک مدل یا یک آبجکت بجای یک Property ساده به صفحه وصل کنید.