عنوان:

‫کتابخانه Ces.WinForm.UI


نویسنده: هادی مزارعی
تاریخ: ۱۴۰۴/۰۳/۱۰ ۰۸:۵۶
آدرس: www.dntips.ir
من همچنان با Windows Form کار میکنم و بدلیل نیاز به بهبود عملکرد برنامه تصمیم گرفتم در حد توانم تعدادی کنترل بدون وابستگی به سایر کتابخانه‌ها ایجاد کنم. مخزن کد (Repository) این کتابخانه بصورت عمومی در دسترس می باشد و بصورت مستمر در حال بروزرسانی است. راهنمای کنترل‌ها در بخش Wiki در دسترس هستند.


مشاهده مطلب اصلی

نظرات

  • هادی مزارعی در ۱۴۰۴/۰۳/۲۱ ۰۹:۵۸
    جلوگیری از رویداد SelectionChanged در نسخه 1.18.4

    مساله
    1. پروژه از نوع Windows Form Application هستش
    2. در یک فرم دو تا DataGridView داریم که یکی در نقش Master و دیگری در نقش Detail
    3. کنترل Grid در دات‌نت در ذات خودش زمانی که مقدار دهی میشه رویداد SelectionChanged رو اجرا میکنه (بدون کلیک کاربر و قبل از تخصیص مقدار جدید).
    4. گرید Master داده‌های مورد نظر رو دریافت کرده و نمایش میده و بصورت خودکار (پیش فرض دات‌نت) سلول اول در حالت انتخال قرار میگره و اگر SelectionMode = FullRow باشه ردیف اول در حالت انتخاب قرار میگیره. در این موقع CurrentCell و یا CurrentRow دیگه null نیستند (که به نظرم خوب هم نیست)
    5. حالا اگر کاربر یک ردیف از گرید Master انتخاب کنه رویداد SelectionCanged از گرید Master گرید Detail رو مقدار دهی می‌کنه در واقع یک API صدا زده میشه و اطلاعات رو دریافت و سپس نمایش میده.
    6. اگر در این زمان کاربر بدون هیچ تغییری در انتخاب ردیف‌های گرید، مجددا داده‌ها را در گرید Master بارگذاری کنه، قبل از تخصیص دیتای جدید بدلیل آنکه ردیف انتخاب شده از حالت انتخاب خارج میشه (متد ClearSelection اجرا میشه) و SelectionChange در گرید Master اجرا میشه و با توجه به اینکه متغیرهای CurrentCell و CurrentRow دارای مقدار هستند بنابراین یکبار دیگه (که اصلا نیاز نیست) گرید Detail مقداردهی میشه.
    7. حالا بعد از بارگذاری دوباره‌ی گرید Master کاربر باید روی ردیف مورد نظر کلیک کنه و گرید Detail مطابق انتخاب جدید مقدار دهی بشه.
    8. تا اینجا گرید Detail سه بار مقداردهی شده. 1) با انتخاب ردیف از گرید Master و 2) قبل از بارگذاری داده‌های جدید در گرید Master و 3) با انتخاب ردیف از گرید Master بعد از بارگذاری اطلاعات جدید. در اینجا مرحله 2 ضروری نیست

    بروزرسانی CesGridView و CesGridViewPro
    در زمان تخصیص اطلاعات از طریق ویژگی CesDataSource ضمن آنکه رویداد OnSelectionChanged اجرا نمیشه بلکه گرید بدون انتخاب سلول و یا ردیف خواهد بود و مقادیر CurrentCell و CurrentRow برابر null هستند. حالا می توان در رویداد SelectionChanged از گرید Master بررسی کرد اگر مقادیر CurrentCell و CurrentRow برابر null بودند (که در نسخه دات‌نت دارای مقدار بودند)، مقدار ویژگی CesDataSource از گرید Detail رو برابر null قرار داد که در این حالت اگر قبلا گرید مقداردهی شده باشد، ستون‌ها حفظ خواهند شد و ردیف‌ها از بین می روند.
  • هادی مزارعی در ۱۴۰۴/۰۳/۲۳ ۰۷:۳۷
    کاهش کد نویسی و بهبود تجربه کاربری با CesComboBox

    از مجموع ویژگی‌های موجود در کنترل CesComboBox، سه ویژگی می تواند به کاهش کد نویسی و بهبود تجربه کاربر کمک کند:

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

    CesSelectFirstItemIfPreviousWasNull
    اگر هیچ آیتمی از قبل انتخاب نشده باشد، اولین آیتم در لیست را بصورت خودکار انتخاب خواهد کرد. فعال بودن این گزینه برای اولین بار که یک فرم نمایش داده می‌شود و هنوز هیچ آیتمی از CesComboBox انتخاب نشده است کاربرد دارد.

    CesSelectFirst
    با فعال کردن این گزینه و بعد از بارگذاری اطلاعات، همیشه اولین آیتم بصورت خودکار انتخاب خواهد شد. فرق اساسی این گزینه با CesKeepPreviousSelection در این است که انتخاب قبلی در این شرایط مهم نیست و فقط یک گزینه باید در CesComboBox در حالت انتخاب باشد ولی در CesKeepPreviousSelection اگر از قبل آیتمی انتخاب شده باشد، کنترل بعد از دریافت Source، آیتم قبلی را انتخاب خواهد کرد.

    اگر گزینه CesKeepPreviousSelection = true باشد مقدار CesSeletFirst = false خواهد بود و برعکس.
    بررسی متدهای GoToValueMember و GoToDisplyMember پیشنهاد می‌گردد.
    • هادی مزارعی در ۱۴۰۴/۰۵/۰۲ ۱۴:۱۶
      در پست قبلی در خصوص ویژگی‌های کنترل CesComboBox مواردی عنوان شد ولی چند مساله وجود دارد که در نسخه 1.18.12 مرتفع شده‌اند.

      کارکرد کنترل قبل از نسخه 1.18.12
      • بعد از تخصیص مقدار به CesDataSource به دلیل آنکه انتخاب قبلی null می‌شد، رویداد CesSelectionChanged فعال می‌شد.
      • اگر ویژگی CesKeepPreviousItem و یا CesSelectFirst فعال می‌بود، پس از تخصیص مقدار به کنترل، متد GoToValueMember از توسط کنترل بصورت خودکار اجرا می‌شد تا انتخاب قبلی کاربر را مجددا فعال کند و این کار باعث می‌شد که برای بار دوم رویداد CesSelectionChanged فعال شود.
      • در واقع اگر در یک برنامه قرار بود اطلاعاتی برمبنای یک آیتم از CesComboBox فراخوانی شود می‌بایست دوبار این اتفاق رخ میداد و برای برنامه هایی که باید یک درخواست API در وب را ارسال کنند مساله جالبی نبود (غیر از آن هم جالب نیست).

      کارکرد کنترل در نسخه 1.18.12
      مساله اول: در زمان تخصیص مقدار به CesDataSource اگر ویژگی‌های CesKeepPreviousItem و یا CesSelectFirst فعال باشند کنترل رویداد را فعال نخواهد کرد بلکه صدا زدن رویداد بعد از انتخاب آیتم قبلی کاربر و یا انتخاب اولین گزینه اتفاق خواهد افتاد. تا اینجا CesComboBox در کارکرد داخلی خودش اصلاح شده و در صورت لزوم رویداد را صدا می‌زند.

      مساله دوم: فرض کنید بعد از اتمام بارگذاری اطلاعات در CesComboBox یک توسعه دهنده حسب نیاز پروژه جداولی که دارای ویژگی IsPinned باشند (تقریبا تمام جداول دارند) باید به عنوان گزینه‌ی دارای الویت، در حالت انتخاب قرار گیرد. بنابراین اقدام به انتخاب آیتمی خواهد کرد که IsPinned = true باشد. مرحله اول که دریافت و بارگذاری اطلاعات است رویداد CesSelectionChanged را اجرا خواهد کرد و آنچه که توسط توسعه دهنده می‌بایست حسب نیاز پروژه در حالت انتخاب باشد نیز رویداد CesSelectionChanged را مجدد اجرا خواهد کرد. باز هم در این سناریو فراخوانی اطلاعات تکراری وجود دارد.

      حل مساله دوم: یک ویژگی جدید با نام CesStopSelcetionChangedEvent اضافه شده که اگر مقدار آن true باشد رویداد اجرا نخواهد شد و به محض اینکه مقدار آن false شود رویداد صدا زده خواهد شد. با این ویژگی میشه کاملا مطمئن بود که بعد از اجرای تمام سناریوها و حسب نیاز رویداد اجرا خواهد شد.

      // توقف اجرای رویداد
      control.CesStopSelectedItemChangedEvent = true;
      
      // بارگذاری داده‌ها
      // انجام سناریوهای مربوط به توسعه برنامه
      
      //اجرای رویداد
      control.CesStopSelectedItemChangedEvent = false;