نمایش نتایج 1 تا 15 از 15

نام تاپیک: الگوریتم برای فقط آخرین فراخوانیِ متد

  1. #1

    الگوریتم برای فقط آخرین فراخوانیِ متد

    سلام دوستان

    فرض کنید که کد زیر را داریم :


    public class A
    {
    private void Caller_1()
    {
    Test();
    }

    public static void Test()
    {
    }
    }


    public class B
    {
    private void Caller_2()
    {
    A.Test();
    }

    private void Caller_3()
    {
    A.Test();
    }
    }


    متدهای با نام Caller در کلاس های مختلف ، قرار هست که یک متد در یک کلاس (متد A.Test) را فراخوانی کنند .
    میخوام آخرین باری که یک متد ، متد Test را فراخوانی کرد ، فقط همون بار این فراخوانی انجام بشه .

    یعنی مثلا اگر متد Caller_1 ، اول اجرا شد ، متد Test را فراخوانی نکنه و اگر بعدش Caller_3 فراخوانی شد ، باز هم متد Test را فراخوانی نکنه و فقط آخرین دفعه ای که فرضا Caller_2 اجرا شد ، فقط این بار ، متد Test را فراخوانی کنه .

    معلوم هم نیست که ترتیب اجرای متدهای Caller ، چطوری هست . مثلا ممکنه در یک دفعه ، فقط یکی از این متدها اجرا بشه و دفعه ی بعد ، 3 تاشون اجرا بشن و همچنین اینکه ممکنه ترتیب هاشون فرق کنن .

    ==============

    من فقط راهکار استفاده از تایمر به ذهنم میرسه .
    یعنی متدهای Caller ، مستقیما متد Test را فراخوانی نکنن و متدی در یه کلاس با یه تایمر را فراخوانی کنن و اون تایمر ، بعد از یک مدت زمان خاص ، فقط یک بار متد Test را فراخوانی کنه .

    که البته این روش ، چندان بهینه نیست . چون ممکنه در یک سیستمی ، وقتی این یک یا دو یا سه متدهای Caller فراخوانی میشن ، مثلا بینِ دو فراخوانیِ این متدها ، مدت زمانش رسیده باشه و اون تایمر ، متد Test را فراخوانی کرده باشه (که در این صورت ، متد Test ، فقط آخرین بار ، اجرا نمیشه و چند بار اجرا میشه) و یا اینکه ممکنه که در یک سیستم دیگه ، مدت زمانش نرسیده باشه و در این صورت ، بیخودی هدر رفتِ زمان و معطلی را در اون سیستم ایجاد میکنه .

    دوستان راهکار بهینه تری سراغ دارن؟
    تشکر

  2. #2
    کاربر دائمی آواتار پرستو پارسایی
    تاریخ عضویت
    آبان 1392
    محل زندگی
    تهران
    پست
    456

    نقل قول: الگوریتم برای فقط آخرین فراخوانیِ متد

    با سلام . ضمن تشکر از زحمات سال های دور . لطفا این کد را در مورد سوال فوق تست بفرمائید.
    public class A
    {
    private static DateTime? lastTestCall = null;
    private static Dictionary<string, DateTime> lastCallerCalls = new Dictionary<string, DateTime>();

    private void Caller_1()
    {
    if (!lastTestCall.HasValue && (!lastCallerCalls.ContainsKey("Caller_1") || lastCallerCalls["Caller_1"] < lastTestCall))
    {
    Test();
    }
    lastCallerCalls["Caller_1"] = DateTime.Now;
    }

    public static void Test()
    {
    lastTestCall = DateTime.Now;
    // کد مربوط به متد Test
    }
    }


    public class B
    {
    private void Caller_2()
    {
    if (!A.lastTestCall.HasValue && (!A.lastCallerCalls.ContainsKey("Caller_2") || A.lastCallerCalls["Caller_2"] < A.lastTestCall))
    {
    A.Test();
    }
    A.lastCallerCalls["Caller_2"] = DateTime.Now;
    }

    private void Caller_3()
    {
    if (!A.lastTestCall.HasValue && (!A.lastCallerCalls.ContainsKey("Caller_3") || A.lastCallerCalls["Caller_3"] < A.lastTestCall))
    {
    A.Test();
    }
    A.lastCallerCalls["Caller_3"] = DateTime.Now;

  3. #3
    کاربر دائمی آواتار ShayanFiroozi
    تاریخ عضویت
    شهریور 1397
    محل زندگی
    بندرعباس ، خلیج همیشه فارس
    سن
    38
    پست
    222

    نقل قول: الگوریتم برای فقط آخرین فراخوانیِ متد

    سلام ،

    میتونین 3 تا متغیر استاتیک به عنوان Flag در نظر بگیرین که در زمان اجرای هر کدوم از Caller ها Flag همون Caller برابر با true بشه ، در هر Caller اگر 2 تا از Flag ها true بودن یعنی در این Caller باید Test اجرا بشه ، و وقتی اجرا شد Flag هاتون رو دوباره false کنین.

  4. #4

    نقل قول: الگوریتم برای فقط آخرین فراخوانیِ متد

    نقل قول نوشته شده توسط پرستو پارسایی مشاهده تاپیک
    با سلام . ضمن تشکر از زحمات سال های دور . لطفا این کد را در مورد سوال فوق تست بفرمائید.
    public class A
    {
    private static DateTime? lastTestCall = null;
    private static Dictionary<string, DateTime> lastCallerCalls = new Dictionary<string, DateTime>();

    private void Caller_1()
    {
    if (!lastTestCall.HasValue && (!lastCallerCalls.ContainsKey("Caller_1") || lastCallerCalls["Caller_1"] < lastTestCall))
    {
    Test();
    }
    lastCallerCalls["Caller_1"] = DateTime.Now;
    }

    public static void Test()
    {
    lastTestCall = DateTime.Now;
    // کد مربوط به متد Test
    }
    }


    public class B
    {
    private void Caller_2()
    {
    if (!A.lastTestCall.HasValue && (!A.lastCallerCalls.ContainsKey("Caller_2") || A.lastCallerCalls["Caller_2"] < A.lastTestCall))
    {
    A.Test();
    }
    A.lastCallerCalls["Caller_2"] = DateTime.Now;
    }

    private void Caller_3()
    {
    if (!A.lastTestCall.HasValue && (!A.lastCallerCalls.ContainsKey("Caller_3") || A.lastCallerCalls["Caller_3"] < A.lastTestCall))
    {
    A.Test();
    }
    A.lastCallerCalls["Caller_3"] = DateTime.Now;
    نقل قول نوشته شده توسط ShayanFiroozi مشاهده تاپیک
    سلام ،

    میتونین 3 تا متغیر استاتیک به عنوان Flag در نظر بگیرین که در زمان اجرای هر کدوم از Caller ها Flag همون Caller برابر با true بشه ، در هر Caller اگر 2 تا از Flag ها true بودن یعنی در این Caller باید Test اجرا بشه ، و وقتی اجرا شد Flag هاتون رو دوباره false کنین.
    سلام
    خیلی ممنون از هر دوی شما .
    خواهش میکنم .

    در کدتون ، اون متدهای Caller ، بررسی میکنن اگر متغییر lastTestCall مقدار نداشت ، کد اجرا میشه که در این صورت فقط یکبار کد اجرا میشه .
    همچنین اینکه روال کار هر دوی شما بزرگواران چون شبیه همدیگه هست ، توضیحات زیر را بدم :

    فکر کنم درک مسئله ای که مطرح کردم ، خوب انجام نشد .
    من میخوام مثلا Caller_1 ، وقتی صدا زده شد ، آیا متد Test فراخوانی بشه؟
    هنوز خودِ متد Caller_1 نمیدونه . باید بفهمه که آیا متدهای Caller_2 یا Caller_3 هم قرار هست که در آینده ، متدِ Test را فراخوانی کنند یا نه .
    اگر یک کدوم از اینها میخوان فراخوانی کنند ، خوب متد Caller_1 ، نباید متد Test را فراخوانی کنه وگرنه باید فراخوانی کنه .

    اینکه متد Caller_1 بخواد از عملی که هنوز انجام نشد ، خبردار بشه ، این کار را سخت و شاید تقریبا نشدنی کنه .
    باز هم ممنون از جواب هر دوی تون .

  5. #5
    کاربر دائمی آواتار ShayanFiroozi
    تاریخ عضویت
    شهریور 1397
    محل زندگی
    بندرعباس ، خلیج همیشه فارس
    سن
    38
    پست
    222

    Question نقل قول: الگوریتم برای فقط آخرین فراخوانیِ متد

    نقل قول نوشته شده توسط SajjadKhati مشاهده تاپیک
    هنوز خودِ متد Caller_1 نمیدونه . باید بفهمه که آیا متدهای Caller_2 یا Caller_3 هم قرار هست که در آینده ، متدِ Test را فراخوانی کنند یا نه .
    بسیار خوب ، شرایط اینکه میخوان اجرا کنند یا نه چی هست ؟

    ضمنا به نظر من بهتره یا شما راه حل تایمر رو گرچه که بهینه نیست پیاده سازی کنین ! و بعد ببینیم راه حل بهتر و بهینه تری براش هست یا نه و یا اینکه شما بفرمایید هدف یا در واقع مسئله کلا چی هست تا شاید درک بهتری صورت بگیره.

    مرسی
    آخرین ویرایش به وسیله ShayanFiroozi : یک شنبه 07 خرداد 1402 در 08:45 صبح

  6. #6
    کاربر دائمی آواتار پرستو پارسایی
    تاریخ عضویت
    آبان 1392
    محل زندگی
    تهران
    پست
    456

    نقل قول: الگوریتم برای فقط آخرین فراخوانیِ متد

    من هم درک مناسبی از مطالب ذکر شده نداشتم با اینحال چیزی که متوجه شدم اینه :

    // Class A with Test method and callerspublic class A
    {
    // Singleton instance of class A
    private static A instance = null;
    // Last time Test method was called
    private DateTime? lastTestCall = null;
    // Dictionary to store last call time of each caller
    private Dictionary<string, DateTime> lastCallerCalls = new Dictionary<string, DateTime>();
    // Get the singleton instance of class A
    public static A Instance
    {
    get
    {
    if (instance == null)
    {
    instance = new A();
    }
    return instance;
    }
    }


    // Private constructor for singleton pattern
    private A() { }


    // Check if Test method can be called based on last call times of Test and callers
    private bool CanCallTest()
    {
    return !lastTestCall.HasValue || lastCallerCalls.Values.All(callTime => callTime < lastTestCall.Value);
    }


    // Update the last call time of a caller
    private void UpdateLastCallerCall(string callerName)
    {
    lastCallerCalls[callerName] = DateTime.Now;
    }


    // Caller_1 method that calls Test method if conditions are met
    public void Caller_1()
    {
    if (CanCallTest())
    {
    Test();
    }
    UpdateLastCallerCall("Caller_1");
    }


    // Test method that performs a certain task
    private void Test()
    {
    lastTestCall = DateTime.Now;
    // Code for the Test method
    NotifyObservers();
    }


    // List of observers that need to be updated when Test method is called
    private List<IObserver> observers = new List<IObserver>();


    // Attach an observer to the list
    public void Attach(IObserver observer)
    {
    observers.Add(observer);
    }


    // Detach an observer from the list
    public void Detach(IObserver observer)
    {
    observers.Remove(observer);
    }


    // Notify all observers in the list
    private void NotifyObservers()
    {
    foreach (IObserver observer in observers)
    {
    observer.Update();
    }
    }
    }


    وبرای کلاس B

    // Class B with callers that call Test method in class Apublic class B
    {
    // Instance of class A
    private A a = A.Instance;


    // Caller_2 method that calls Test method in class A if conditions are met
    public void Caller_2()
    {
    if (a.CanCallTest())
    {
    a.Test();
    }
    a.UpdateLastCallerCall("Caller_2");
    }


    // Caller_3 method that calls Test method in class A if conditions are met
    public void Caller_3()
    {
    if (a.CanCallTest())
    {
    a.Test();
    }
    a.UpdateLastCallerCall("Caller_3");
    }
    }
    آخرین ویرایش به وسیله پرستو پارسایی : یک شنبه 07 خرداد 1402 در 14:11 عصر

  7. #7

    نقل قول: الگوریتم برای فقط آخرین فراخوانیِ متد

    نقل قول نوشته شده توسط ShayanFiroozi مشاهده تاپیک
    بسیار خوب ، شرایط اینکه میخوان اجرا کنند یا نه چی هست ؟
    سلامی مجدد
    ممنون .

    دقیقا متوجه ی منظورتون نشدم .

    نقل قول نوشته شده توسط ShayanFiroozi مشاهده تاپیک
    یا اینکه شما بفرمایید هدف یا در واقع مسئله کلا چی هست تا شاید درک بهتری صورت بگیره.

    مرسی
    جریان اینه که کلاس ها و پروپرتی هایی هستند که Binding ئه 2 طرفه میخوام انجام بدم (در wpf) .
    هدف بایندینگ (Binding Target) ، کنترل DataGrid هست و منبع بایندینگ (Binding Source) ، شی ای از کلاس Person (پروپرتی های مختلف در DataGrid ، به پروپرتی های مختلف در Person ، متصل و Binding ئه 2 طرفه میشن) .

    کلاس Person ، علاوه بر پروپرتی هایی که اطلاعات نوع اساسی (مثل string و int و ...) را ذخیره میکنه ، پروپرتی هایی از نوع کالکشن ای از کلاس های دیگه مثل کلاس (MobileNumber و Address) را هم داره که این کلاس ها هم خودشون شامل پروپرتی ها از نوع داده های اساسی دارند که اطلاعات مورد نظر را ذخیره میکنند (کلاس Address در کد زیر نیامد) :


    public class PhoneBook
    {
    public ObservableCollection<Person> Persons { get; set; }
    }


    public class Person : INotifyPropertyChanged
    {
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public ObservableCollection<MobileNumber> MobileNumbers { get; set; }
    }


    public class MobileNumber : INotifyPropertyChanged
    {
    public int Id{ get; set; }
    public string MobileNumber{ get; set; }
    }


    با انجام Binding ئه 2 طرفه ، نهایتا مثلا چند تا پروپرتی را که تغییر دادیم ، بخشِ (accessor) ئه set ئه پروپرتیِ مورد نظر تغییر میکنه .
    مثلا کاربر ممکنه که FirstName و MobileNumber را در پروپرتی های بالا ، تغییر بده یا اضافه کنه (ممکنه حتی یه دونه پروپرتی یا ممکنه خیلی بیشتر از این ها را تغییر بده یا اضافه کنه) .

    اما من فقط شیِ Person را میخوام . یعنی چه یه پروپرتی تغییر کنه یا مقدار جدیدی اضافه بشه یا اینکه 10 تا پروپرتی تغییر کنن ، واسه ی من ، فقط مهم این هست که این پروپرتی ها فقط یکبار اعلام کنن که شیِ Person ام تغییر کردن (اون هم آخرین پروپرتی ای که تغییر کرد ، باید اعلام کنه) .

    یعنی مثلا کاربر که اول ، FirstName را تغییر داد و بعد MobileNumber را تغییر داد ، واسه ی من ، فقط تغییر مقدار پروپرتی آخری که MobileNumber هست ، مهم هست .

    -------------------

    از طرفی هم در Binding ئه دو طرفه ، چون مدیریت اضافه و کم کردن کدها ، چندان دست ما نیست (کنترل ها و موتور بایندینگ wpf ، بصورت اتوماتیک این کار را میکنه) ، خیلی نمیشه زمان کدها را مدیریت کامل کرد . البته شدن ، شاید بشه که توضیح میدم .

    یعنی مثلا مثل حالت عادی که یه فرم باز میشه و وقتی کاربر فرم را بست ، برنامه نویس از رویدادِ بستنِ فرم متوجه میشه که مقادیر توسط کاربر داده شد ، در این حالت ، چندان این طور نیست و باید از رویدادهایی که پراکنده هستن ، این موارد را متوجه شد .


    هر چند ، برای من ، فقط حذف و اضافه و ویرایش شدن شیِ Person مهم هست (یعنی حذف و اضافه و ویرایش شدن شی زیر مجموعه اش که MobileNumber و ... باشه ، فعلا مهم نیست) و موقع حذف و اضافه و ویرایش شدن شیِ Person ، میتونیم توسط کلاسی که از ValidationRule ارث بری میکنه ، به نوعی از زمان حذف و اضافه و ویرایش شدن شیِ Person با خبر بشیم اما بخاطر مشکلی در طراحی کنترل DataGrid (اطلاعاتی که میخواد برای ویرایش شدن بفرسته را قبل از اینکه به لایه ی منطق تجاری بفرسته ، به ما نمیده ؛ باز هم هر چند میشه کدنویسی این مشکل را رفع کرد اما چون کدها را پیچیده میکنه و مخصوصا ممکنه در ویرایش نسخه های بعدی ، کار را سخت کنه ، از این روش استفاده نمیکنم) ، باید جوری این رو تنظیم کنم که بعد از اینکه اطلاعات را به لایه ی منطق تجاری منتقل کرد ، بعد متدی در کلاس ValidationRule اجرا بشه .

    بنابراین راهکار دیگه ای فعلا پیدا نکردم که بتونم متوجه بشم که کاربر چه وقتی فقط شیِ Person را حذف یا اضافه و ویرایش میکنه (مگر اینکه از تغییر تک تکِ هر پروپرتی در هر کلاس متوجه بشم که این هم ، همین مشکلی را داره که در این تاپیک مطرح کردم) .

    نمیدونم چرا کنترل اعتبارسنجی را در DataGrid ، این طوری طراحی کرد مایکروسافت!
    نمیدونم کنترل های شرکت های دیگه هم همین مشکل را داره (که قبل از ارسال داده اش به Binding Source ، اون اطلاعات را به کاربر ارائه میده) یا نه !
    تشکر

  8. #8

    نقل قول: الگوریتم برای فقط آخرین فراخوانیِ متد

    نقل قول نوشته شده توسط پرستو پارسایی مشاهده تاپیک
    من هم درک مناسبی از مطالب ذکر شده نداشتم با اینحال چیزی که متوجه شدم اینه :

    // Class A with Test method and callerspublic class A
    {
    // Singleton instance of class A
    private static A instance = null;
    // Last time Test method was called
    private DateTime? lastTestCall = null;
    // Dictionary to store last call time of each caller
    private Dictionary<string, DateTime> lastCallerCalls = new Dictionary<string, DateTime>();
    // Get the singleton instance of class A
    public static A Instance
    {
    get
    {
    if (instance == null)
    {
    instance = new A();
    }
    return instance;
    }
    }


    // Private constructor for singleton pattern
    private A() { }


    // Check if Test method can be called based on last call times of Test and callers
    private bool CanCallTest()
    {
    return !lastTestCall.HasValue || lastCallerCalls.Values.All(callTime => callTime < lastTestCall.Value);
    }


    // Update the last call time of a caller
    private void UpdateLastCallerCall(string callerName)
    {
    lastCallerCalls[callerName] = DateTime.Now;
    }


    // Caller_1 method that calls Test method if conditions are met
    public void Caller_1()
    {
    if (CanCallTest())
    {
    Test();
    }
    UpdateLastCallerCall("Caller_1");
    }


    // Test method that performs a certain task
    private void Test()
    {
    lastTestCall = DateTime.Now;
    // Code for the Test method
    NotifyObservers();
    }


    // List of observers that need to be updated when Test method is called
    private List<IObserver> observers = new List<IObserver>();


    // Attach an observer to the list
    public void Attach(IObserver observer)
    {
    observers.Add(observer);
    }


    // Detach an observer from the list
    public void Detach(IObserver observer)
    {
    observers.Remove(observer);
    }


    // Notify all observers in the list
    private void NotifyObservers()
    {
    foreach (IObserver observer in observers)
    {
    observer.Update();
    }
    }
    }


    وبرای کلاس B

    // Class B with callers that call Test method in class Apublic class B
    {
    // Instance of class A
    private A a = A.Instance;


    // Caller_2 method that calls Test method in class A if conditions are met
    public void Caller_2()
    {
    if (a.CanCallTest())
    {
    a.Test();
    }
    a.UpdateLastCallerCall("Caller_2");
    }


    // Caller_3 method that calls Test method in class A if conditions are met
    public void Caller_3()
    {
    if (a.CanCallTest())
    {
    a.Test();
    }
    a.UpdateLastCallerCall("Caller_3");
    }
    }
    سلامی مجدد
    ممنون .

    به نظر میرسه روال کد ، همون مثل قبل هست .
    اما سناریو را گفته بودم . ببینید سناریو اش ، خیلی شبیه به سناریوی مزایده هست .
    مشتری هایی وجود دارند (متدهای Caller) که میخوان به فروشنده (متد Test) ، یک قیمتی را اعلام کنند (متدش را فراخوانی کنند) .
    اما آیا فروشنده ، با اعلام هر مشتری ، لازم میدونه که عمل فروش را انجام بده؟
    نه .
    بلکه فروشنده ، با هر بار اعلامِ مشتری ، باز از همه ی مشتریانِ دیگه میپرسه که آیا قصد خریدِ کالا اش را دارند یا نه .
    سناریو ، شبیه به این هست .

    لطفا کد ندین (مگر اینکه متوجه نشم) . اگه مایل بودید ، اول ، سناریوی تون را برای حل این مشکل بگین ، ببینم شدنی هست؟
    تشکر

  9. #9
    کاربر دائمی آواتار ShayanFiroozi
    تاریخ عضویت
    شهریور 1397
    محل زندگی
    بندرعباس ، خلیج همیشه فارس
    سن
    38
    پست
    222

    Lightbulb نقل قول: الگوریتم برای فقط آخرین فراخوانیِ متد

    اضافه ، حذف و یا ویرایش به صورت مستقیم روی Datagrid انجام میشه ؟

    واینکه فکر کنم Observabe Pattern که خانم پارسایی توضیح دادن بتونه کمک کنه.
    ضمنا Datagrid شرکت های دیگه رو تجربه نکردم ، باشد تست کنین.

    و در خصوص راه حل خودتون

    نقل قول نوشته شده توسط SajjadKhati مشاهده تاپیک
    بنابراین راهکار دیگه ای فعلا پیدا نکردم که بتونم متوجه بشم که کاربر چه وقتی فقط شیِ Person را حذف یا اضافه و ویرایش میکنه (مگر اینکه از تغییر تک تکِ هر پروپرتی در هر کلاس متوجه بشم که این هم ، همین مشکلی را داره که در این تاپیک مطرح کردم) .
    تشکر
    اگر روش شما فقط مشکل بهینه نبودن رو داره که شاید بشه کاریش کرد ، اگر پیاده سازی کردین لطف کنین ارسال کنین ، شاید با استفاده از Reflection ها بتونیم روش جدید پیاده سازی کنیم.

  10. #10

    نقل قول: الگوریتم برای فقط آخرین فراخوانیِ متد

    نقل قول نوشته شده توسط ShayanFiroozi مشاهده تاپیک
    اضافه ، حذف و یا ویرایش به صورت مستقیم روی Datagrid انجام میشه ؟
    توسط Binding ئه 2 طرفه انجام میشه .
    مستقیما کدی را برای تغییر نوشته نمیشه (مگر اینکه لایه ی منطق تجاری را از لایه ی view بخوام دستکاری کنم که اون هم شاید انجام نشه) (حداقل اینکه خیلی بعیده مخصوصا تغییر در view) .

    نقل قول نوشته شده توسط ShayanFiroozi مشاهده تاپیک
    واینکه فکر کنم Observabe Pattern که خانم پارسایی توضیح دادن بتونه کمک کنه.
    ضمنا Datagrid شرکت های دیگه رو تجربه نکردم ، باشد تست کنین.
    Observer Pattern ، برای اطلاع دادن یک وضعیت هست . مثلا مقداری از یک شی ای میخواهد تغییر کند یا اینکه تغییر کرد را اطلاع میدهد .

    اما من میخوام بدونم آیا وقتی این اتفاق افتاد (مقدار یک شی تغییر کرد) ، آیا شی های دیگر هم مقدارشون در آینده تغییر میکنند یا نه؟
    آینده ای که هنوز اتفاق نیفتاد ، و اون شی هنوز نمیدونه ، حداقل با این الگوی طراحی قابل پیاده سازی نیست .

    ضمن اینکه اصلا معلوم نیست قابل پیاده سازی باشه یا نه .
    مثلا شاید با الگوریتم های پیچیده ی هوش مصنوعی بشه متوجه شد اما من بلد نیستم .

    نقل قول نوشته شده توسط ShayanFiroozi مشاهده تاپیک
    و در خصوص راه حل خودتون



    اگر روش شما فقط مشکل بهینه نبودن رو داره که شاید بشه کاریش کرد ، اگر پیاده سازی کردین لطف کنین ارسال کنین ، شاید با استفاده از Reflection ها بتونیم روش جدید پیاده سازی کنیم.
    reflection ها که ربطی به این موضوع ندارن .
    reflection ها برای مدیریت شی ها زمان اجراست . من با شی ها مشکلی ندارم . زمان طراحی و کمپایل هم میتونم باهاشون کار کنم .
    میخوام از وضعیت شی از آینده مطلع شم .

    تشکر .

  11. #11

    نقل قول: الگوریتم برای فقط آخرین فراخوانیِ متد

    آقای SajjadKhati چرا اینقدر یک مسئله رو بد توضیح میدی. تازه توی پست هفتم ما باید بفهمیم سوال اصلی چیه!!!


    فکر کن داری برای ویندوزفرم یا هر پلتفرم دیگری کد مینویسی. چطور متوجه میشی که یک سطر ویرایش شده و آماده اعتبارسنجی و ثبت تغییرات در دیتابیس هست؟

  12. #12
    کاربر دائمی آواتار پرستو پارسایی
    تاریخ عضویت
    آبان 1392
    محل زندگی
    تهران
    پست
    456

    نقل قول: الگوریتم برای فقط آخرین فراخوانیِ متد

    سلام با توجه به نحوه پرسش آقای Mohamoud.Afrad گرامی ، به نظرم برای اینکه بتوانیم در ویندوز فرم به تغییرات در داده ها ی ویرایش شده دسترسی پیدا کرده و آن ها را اعتبارسنجی و در دیتابیس ذخیره کنیم، می توانیم از رویداد PropertyChanged استفاده کنیم و در آن، کدی برای اعتبارسنجی و ذخیره تغییرات در دیتابیس بنویسیم.


    public class Person : INotifyPropertyChanged
    {
    public event PropertyChangedEventHandler PropertyChanged;


    private int id;
    public int Id
    {
    get { return id; }
    set
    {
    if (id != value)
    {
    id = value;
    OnPropertyChanged(nameof(Id));
    }
    }
    }


    private string firstName;
    public string FirstName
    {
    get { return firstName; }
    set
    {
    if (firstName != value)
    {
    firstName = value;
    OnPropertyChanged(nameof(FirstName));
    }
    }
    }


    private string lastName;
    public string LastName
    {
    get { return lastName; }
    set
    {
    if (lastName != value)
    {
    lastName = value;
    OnPropertyChanged(nameof(LastName));
    }
    }
    }


    public ObservableCollection<MobileNumber> MobileNumbers { get; set; }


    protected virtual void OnPropertyChanged(string propertyName)
    {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    }


    در این کد، برای هر ویژگی که تغییر می کند، رویداد PropertyChanged فراخوانی می شود و با استفاده از nameof()، نام ویژگی تغییر یافته را به عنوان پارامتر به رویداد PropertyChanged ارسال می شود. سپس در بخش مدیریت رویداد می توانید کدی برای اعتبارسنجی و ذخیره تغییرات در دیتابیس بنویسیم

    public void Person_PropertyChanged(object sender, PropertyChangedEventArgs e){
    if (e.PropertyName == nameof(Person.FirstName))
    {
    // اعتبارسنجی و ذخیره تغییرات در دیتابیس
    }
    else if (e.PropertyName == nameof(Person.LastName))
    {
    // اعتبارسنجی و ذخیره تغییرات در دیتابیس
    }


    البته این کد بر مبنای کد ارسالی خودتان بود و برای اینکه منظورم را درست عنوان کنم کد ارسال کردم

  13. #13

    نقل قول: الگوریتم برای فقط آخرین فراخوانیِ متد

    نقل قول نوشته شده توسط Mahmoud.Afrad مشاهده تاپیک
    آقای SajjadKhati چرا اینقدر یک مسئله رو بد توضیح میدی. تازه توی پست هفتم ما باید بفهمیم سوال اصلی چیه!!!
    سلام آقا محمد .
    آقا شهروز گفتن که جریان کلی را توضیح بدم (شاید روال دیگه ای باشه و کلا این روال لازم نباشه) ، برای همین توی پست 7 توضیحات کلی را دادم .

    بله درست میگید . ببخشید .
    راستش مسائل ریز و این نوع طراحی باعث شده خودم هم یه کم گیج بشم و چند روال متفاوت را بررسی کنم .

    خلاصه اینکه بجای این روش ، از ترکیبی از رویدادهای DataGrid.RowEditEnding و DataGrid.AddingNewItem و فلگ هایی در کلاس مشتق ValidationRule و همچنین تنظیم اجرای ValidationRule بعد از تنظیم و تغییر پروپرتی ها در Model استفاده کردم (در تست اولیه فعلا الحمدلله کار میکنه) .

    نقل قول نوشته شده توسط Mahmoud.Afrad مشاهده تاپیک
    فکر کن داری برای ویندوزفرم یا هر پلتفرم دیگری کد مینویسی. چطور متوجه میشی که یک سطر ویرایش شده و آماده اعتبارسنجی و ثبت تغییرات در دیتابیس هست؟
    پلتفرم شاید زیاد مهم نباشه (برای اطلاعات بیشتر ، گفتم) .
    مسئله ، Binding ئه دو طرفه بود که توضیح داده بودم . یعنی مثلا جوری نیست که یک فرم ای بسته بشه و بعد از بستن ، کنترل کامل در دست برنامه نویس باشه که چه کار کنه (که در پست قبلی توضیح بیشتر داده بودم) .

  14. #14

    نقل قول: الگوریتم برای فقط آخرین فراخوانیِ متد

    نقل قول نوشته شده توسط پرستو پارسایی مشاهده تاپیک
    سلام با توجه به نحوه پرسش آقای Mohamoud.Afrad گرامی ، به نظرم برای اینکه بتوانیم در ویندوز فرم به تغییرات در داده ها ی ویرایش شده دسترسی پیدا کرده و آن ها را اعتبارسنجی و در دیتابیس ذخیره کنیم، می توانیم از رویداد PropertyChanged استفاده کنیم و در آن، کدی برای اعتبارسنجی و ذخیره تغییرات در دیتابیس بنویسیم.


    public class Person : INotifyPropertyChanged
    {
    public event PropertyChangedEventHandler PropertyChanged;


    private int id;
    public int Id
    {
    get { return id; }
    set
    {
    if (id != value)
    {
    id = value;
    OnPropertyChanged(nameof(Id));
    }
    }
    }


    private string firstName;
    public string FirstName
    {
    get { return firstName; }
    set
    {
    if (firstName != value)
    {
    firstName = value;
    OnPropertyChanged(nameof(FirstName));
    }
    }
    }


    private string lastName;
    public string LastName
    {
    get { return lastName; }
    set
    {
    if (lastName != value)
    {
    lastName = value;
    OnPropertyChanged(nameof(LastName));
    }
    }
    }


    public ObservableCollection<MobileNumber> MobileNumbers { get; set; }


    protected virtual void OnPropertyChanged(string propertyName)
    {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
    }


    در این کد، برای هر ویژگی که تغییر می کند، رویداد PropertyChanged فراخوانی می شود و با استفاده از nameof()، نام ویژگی تغییر یافته را به عنوان پارامتر به رویداد PropertyChanged ارسال می شود. سپس در بخش مدیریت رویداد می توانید کدی برای اعتبارسنجی و ذخیره تغییرات در دیتابیس بنویسیم

    public void Person_PropertyChanged(object sender, PropertyChangedEventArgs e){
    if (e.PropertyName == nameof(Person.FirstName))
    {
    // اعتبارسنجی و ذخیره تغییرات در دیتابیس
    }
    else if (e.PropertyName == nameof(Person.LastName))
    {
    // اعتبارسنجی و ذخیره تغییرات در دیتابیس
    }


    البته این کد بر مبنای کد ارسالی خودتان بود و برای اینکه منظورم را درست عنوان کنم کد ارسال کردم
    سلام مجدد
    خیلی ممنونم .
    از یه روال دیگه رفتم و فعلا الحمدلله کار میکنه (که در پست قبلی توضیح دادم) .

    تشکر

  15. #15

    نقل قول: الگوریتم برای فقط آخرین فراخوانیِ متد

    آفرین، توی این مساله پلتفرم مهم نیست پس اینکه بایندینگ دوطرفه دارید هم مهم نیست.

    راه حل
    1- بعد از اعمال تغییرات، کاربر را مجبور به ثبت تغییرات کنید. مثلا با فشردن یک دکمه.
    2- با تغییر هر پراپرتی ، تغییرات رو اعمال کنید. (رویداد در سطح مدل) ... مثال خانم پارسایی
    3- رویداد در سطح view . رویدادهایی مثل تغییر سطر یا خارج شدن از حالت ادیت یک سلول یا ردیف دیتاگرید، که خودتون ازش استفاده کردید

تاپیک های مشابه

  1. پاسخ: 1
    آخرین پست: سه شنبه 31 تیر 1393, 19:23 عصر

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •