عنوان:

‫کنترل DatePicker شمسی مخصوص Silverlight 4


نویسنده: وحید نصیری
تاریخ: ۱۳۸۹/۰۶/۲۵ ۲۳:۰۸:۰۰
آدرس: www.dntips.ir

Silverlight 4 تاریخ شمسی را از دات نت فریم ورک به ارث نبرده است (+). اما اضافه کردن آن کار خاصی نیست. مجموعه‌ی سورس باز Silverlight toolkit هم دارای DatePicker تاریخ میلادی است اما به دلایلی که عرض شد، تاریخ شمسی را پشتیبانی نمی‌کند.

کارهایی که توسط سایر برنامه نویس‌های ایرانی تابحال در این مورد انجام شده است:
- اضافه کردن DatePicker فارسی به مجموعه‌ی Silverlight toolkit : (+)
به دو دلیل من از این راه حل استفاده نخواهم کرد:
الف) patch ارائه شده هنوز با Silverlight toolkit یکپارچه نشده است و هربار باید این تغییرات را اعمال کرد و غیره ...
ب) شاید من اصلا نخواهم که از Silverlight toolkit استفاده کنم. آن وقت چه باید کرد؟
این تنها کاری است که جهت Silverlight انجام شده است.

دو نمونه‌ی خوب دیگر هم برای WPF موجود است که تبدیل آن‌ها به Silverlight کار ساده‌ای نیست (چون Silverlight تمام کلاس‌های WPF را نیز به ارث نبرده است):
- Farsi Library - Working with Dates, Calendars, and DatePickers
- PersianDate and some WPF controls for it

به همین جهت یک کنترل DatePicker و تقویم شمسی مستقل را برای Silverlight 4 آماده کرده‌ام که از آدرس ذیل قابل دریافت است:





نحوه استفاده:
الف) ارجاعی را به اسمبلی SilverlightPersianDatePicker.dll به پروژه خود اضافه کنید. اگر مباحث library caching هم برای شما مهم است، فایل SilverlightPersianDatePicker.extmap.xml پیوست شده را نیز فراموش نکنید.
ب) xmlns آن باید به XAML جاری اضافه شود؛ برای مثال:
xmlns:dp="clr-namespace:SilverlightPersianDatePicker.Views;assembly=SilverlightPersianDatePicker"
ج) سپس استفاده از آن به سادگی یک سطر زیر خواهد بود:
<dp:PDatePicker x:Name="txtDate" TextBoxWidth="100"  Margin="5"  />

خاصیت SelectedDate آن تاریخ میلادی و خاصیت SelectedPersianDate آن تاریخ شمسی را بر می‌گرداند.


کتابخانه‌های کمکی که در حین توسعه‌ی آن استفاده شدند:
کلاس تقویم شمسی امید خندان راد (که برای روزهای دات نت 1 تهیه شده بود).
پنل UniformGrid که در Silverlight موجود نیست.(+)
رفتار StaysOpen مرتبط با Popup که در Silverlight از WPF به ارث نرسیده است.(+)
استفاده از کلاس DelegateCommand جان پاپا (برای سهولت Commanding در الگوی MVVM). (+)


نظرات

  • مهمان در ۱۳۸۹/۰۶/۲۶ ۰۱:۵۸:۱۵
    سلام آقای نصیری
    کارتون عالیه، فقط اگر پروژه رو بذارید روی کدپلکس به نظرتون بهتر نیست؟
  • مهمان در ۱۳۸۹/۰۶/۲۶ ۱۰:۳۹:۱۴
    کار ارزنده ای انجام دادید.
    این روش Commanding حجم کد رو در VM زیاد میکنه، در یک پروژه که رویدادهای زیادی داره(مثلا چند تا برای TreeVirw و چندین دکمه و ...) پیدا کردن قسمتهای مختلف سخت میشه(البته CodeMap هست ولی خب...)
    من در پروژه هام به ازای هر View یک پوشه در Commands ایجاد میکنم و Commandها رو به طور جداگانه ایجاد میکنم.

    نام متدها رو با حرف کوچیک شروع کردین، دلیل خاصی داره؟(Naming Style کلی با حرف بزرگ شروع میشه)
  • وحید نصیری در ۱۳۸۹/۰۶/۲۶ ۱۱:۴۲:۱۴
    @iMAN
    - فکر خوبیه. انجام شد:
    http://slpdatepicker.codeplex.com/

    @Meysam
    - هدف بالا بردن تست پذیری برنامه است. مدیریت نهایی آن دیگر با شما است.
    - بله. در سی شارپ private methods باید با حروف کوچک شروع شوند و public methods با حروف بزرگ.
  • مهمان در ۱۳۸۹/۰۶/۲۷ ۱۶:۴۱:۲۹
    عالی بود، خسته نباشید.
  • وحید نصیری در ۱۳۸۹/۰۶/۲۸ ۰۰:۱۳:۵۵
    2 مثال دیگر هم اضافه کردم که از آدرس زیر قابل دریافت است:
    http://slpdatepicker.codeplex.com/SourceControl/list/changesets
  • مهمان در ۱۳۸۹/۰۶/۲۹ ۱۹:۰۸:۱۶
    Commanding رو میشه بیشتر توضیح بدید؟
  • وحید نصیری در ۱۳۸۹/۰۶/۲۹ ۱۹:۲۴:۳۰
    بله. مراجعه کنید به کتاب سیلورلایتی که منتشر شد قسمت‌های MVVM آن. مفصل در طی چند فصل از پایه توضیح داده شده است:
    SL04.zip
  • مهمان در ۱۳۸۹/۰۷/۱۶ ۱۲:۴۸:۵۴
    سلام.
    با تشکر از زحمتی که کشیدید :)
    استفاده در WPF هم ممکن هست؟
  • وحید نصیری در ۱۳۸۹/۰۷/۱۶ ۱۷:۱۲:۰۵
    سلام،
    برای WPF می‌تونید از مواردی که نامبرده شد استفاده کنید.
    + این کامپوننت نیاز هست کمی تغییر کند تا برای WPF هم قابل استفاده شود. WPF خیلی از مواردی را که در آخر بحث فوق ذکر شد را دارد (مانند uniform grid ، تقویم شمسی و غیره). این‌ها باید حذف شوند. رفتار popup در wpf بسیار پخته‌تر است و کاملتر و این مورد هم باید کمی تعدیل شود. مابقی موارد با یک کامپایل در پروژه‌ی جدید مخصوص WPF قابل استفاده خواهد بود. مثال‌های آن هم تفاوتی نمی‌کند.
    وقت کنم به زودی این رو به WPF هم انتقال می‌دم.
  • وحید نصیری در ۱۳۸۹/۰۸/۱۳ ۰۰:۰۴:۰۳
    نسخه WPF آن هم اضافه شد. برای دریافت، به سایت CodePlex مراجعه کنید: (+)
  • مهمان در ۱۳۸۹/۰۹/۱۶ ۲۰:۰۴:۴۸
    سلام،
    با تشکر از کار ارزشمندتان.
    با دیدن ToPersianNumberConverter در پروژه، برایم این سئوال پیش آمد که چرا نمیتوان از خصوصیت FrameworkElement.Language در Silverlight استفاده کرد؟
  • وحید نصیری در ۱۳۸۹/۰۹/۱۶ ۲۲:۳۱:۵۸
    تقریبا تمام کنترل‌های سیلورلایت دارای خاصیت language هم هستند اما تنظیم آن به fa-IR اثری ندارد یا برای مثال مطابق این مقاله (+) می‌شود فرهنگ خاصی را به برنامه در CurrentCulture و CurrentUICulture ترد جاری آن اعمال کرد که باز هم fa-IR اثری ندارد. علت آن‌را اینجا مطالعه کنید: (+)
  • مهمان در ۱۳۹۰/۰۲/۰۵ ۰۹:۴۲:۱۱
    با سلام
    با تشکر از زحمتی که کشیدید ، آیا امکان تبدیل تاریخ رو هم داره ؟ یا فکری به حال تبدیل تاریخ ها کردید ؟ واقعا معزل بزرگی شده
  • وحید نصیری در ۱۳۹۰/۰۲/۰۵ ۰۹:۴۳:۴۰
    بله؛ لطفا سورس را از کد پلکس دریافت کنید، کتابخانه مربوطه به همراه سورس هست
  • مهمان در ۱۳۹۱/۰۶/۱۹ ۱۳:۴۰
    با سلام و تشکر
    ممکنه بفرمایین چطوری میشه از این کامپوننت تو vb.net 2010 استفاده کرد؟



    • وحید نصیری در ۱۳۹۱/۰۶/۱۹ ۱۳:۵۴
      آنچنان تفاوتی بین کدهای XAML نوشته شده فوق (در قسمت نحوه استفاده) با معادل VB.NET آن نیست. فقط این تفاوت کوچک را مدنظر داشته باشید.
  • مهمان در ۱۳۹۱/۰۶/۱۹ ۱۹:۵۵
    با تشکر از جواب سریعتون
    کامپوننت رو آوردم و استفاده میکنم ولی موقع اجرای برنامه وقتی stop می‌کنم و می‌خوام به محیط VS 2010 برگردم 2 تاwarning  میده و فرم رو در حالت design نشون نمیده

      1- [A]WpfPersianDatePicker.Views.PDatePicker cannot be cast to [B]WpfPersianDatePicker.Views.PDatePicker. Type A originates from 'WpfPersianDatePicker, Version=1.1.0.0, Culture=neutral, PublicKeyToken=e5d899545a6585ee' in the context 'LoadNeither' at location 'C:\Documents and Settings\HV\Local Settings\Application Data\Microsoft\VisualStudio\10.0\ProjectAssemblies\zgrq7cfx01\WpfPersianDatePicker.DLL'. Type B originates from 'WpfPersianDatePicker, Version=1.1.0.0, Culture=neutral, PublicKeyToken=e5d899545a6585ee' in the context 'Default' at location 'C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\WpfPersianDatePicker.dll'
    2-
    The variable 'UserControl11' is either undeclared or was never assigned. 
    فکر می‌کنم خطای دوم همونیه که شما راهنمایی فرمودین ولی من نتونستم جاشو پیدا کنم
    یه سوال دیگه من دارم تاریخ رو از پایگاه می‌خونم می‌تونم تو این کامپوننت موقع لود شدن صفحه بنویسمش مثل dateTimepicker معمولی؟
    • وحید نصیری در ۱۳۹۱/۰۶/۱۹ ۲۰:۵۷
      چندتا مطلب هست:
      - احتمالا منظور شما از VB.NET همان WPF بوده و این بحث جاری هم سیلورلایت است. نسخه WPF این کنترل هم موجود است. باید سورس‌ها را دریافت کنید و کامپایل. مثال WPF هم دارد در سورس‌های مجموعه (در پوشه WpfPersianDatePickerUsage).
      - خطایی که نوشتید مشکل VS.NET است که در دو جای مختلف به دنبال یک سری اسمبلی می‌گردد. در مسیر ProjectAssemblies\zgrq7cfx01 و در مسیر Common7\IDE. این تداخل رو می‌تونید با پاک کردن پوشه‌های obj و bin و مسیرهای یاد شده و بعد rebuild کامل پروژه احتمالا برطرف کنید. در کل مشکل کنترل دریافتی نیست. تداخل نگارش‌ها رخ داده روی سیستم شما.
      - بله. مراجعه کنید به مثال موجود در پوشه WpfPersianDatePickerUsage. (سورس را باید دریافت کنید)
  • مهمان در ۱۳۹۱/۰۷/۱۴ ۱۵:۲۵
    جناب آقای نصیری من هر روشی که میتونستم امتحان کردم تا از این کامپوننت توی پروژه VB.Net 2010 خودم استفاده کنم ولی نشد.
    ممکنه یکبار نحوه استفاده رو توی wpf کامل توضیح بدید؟
    من این کارهارو می‌کنم:
    1 - add>usercontrol> wpf
    2- add کردن dll به toolBox
    3- drag کردن pdatepicker توی usercontrol و rebuild کلی پروژه
    4- اضافه کردن elementhost به فرم
    5- انتخاب usercontrol به elementhost

    موقع اجرا تقویم رو توی فرم نشون میده ولی وقتی می‌خوام تاریخ رو ازش انتخاب بکنم
    Error:
    object reference is not set to an object
    use new keyword ....


    • وحید نصیری در ۱۳۹۱/۰۷/۱۸ ۲۳:۴۵
      یک مثال WinForms هم اضافه کردم.
  • مهمان در ۱۳۹۱/۰۷/۲۳ ۱۳:۲۴
    جناب آقای نصیری
    من دقیقا همون کارهارو کردم ولی اینبار با این مثالی که فرستاده بودید کار کرد!
    خیلی ممنون
    ممکنه لطفا توی همین مثال یک خط هم اضافه کنید که نحوه مقداردهی رو نشون بده. یعنی تاریخ رو از یک جای دیگه بگیره (مثلا از تقویم دیگه یا textBox)
    مثال هایی که تو سیلور لایت دارید این قابلیت رو دارن اگر ممکنه توی همین پروژه winform هم اضافه کنید

    خیلی ممنون

    • وحید نصیری در ۱۳۹۱/۰۷/۲۳ ۱۴:۲۴
      در همان مثال سورس‌های برنامه، روش زیر هم کار می‌کند (SelectedPersianDate خواندنی و نوشتنی است):
      datePicker.SelectedPersianDate = "1391/7/23"

  • سیروان عفیفی در ۱۳۹۴/۰۴/۰۱ ۱۱:۱۳
    سلام، ظاهراً issue tracker پروژه در codeplex مشکل داره، مجبور شدم اینجا سوالم رو مطرح کنم(ببخشید):
    DLL مربوط در پروژه اضافه شده و به خوبی کار میکند، منتها وقتی می‌خوام از کلاس PersianCalendar استفاده کنم در زمان build پروژه خطای زیر رو دریافت میکنم:
    Error143The type 'System.Globalization.PersianCalendar' exists in both 'c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Silverlight\v5.0\mscorlib.dll' and '....\SilverlightPersianDatePicker.dll'
    برای رفع این تداخل چه پیشنهادی میدهید؟
    ممنون از شما
    • وحید نصیری در ۱۳۹۴/۰۴/۰۱ ۱۱:۴۶
      احتمالا از نسخه‌ی سیلورلایت 4 استفاده می‌کنید. بهتر است سورس نهایی را از اینجا دریافت و کامپایل کنید. این سورس به روزتر است از DLLهای منتشر شده. خصوصا نسخه‌ی WPF آن تغییرات زیادی داشته‌است که فقط از قسمت سورس‌ها قابل دریافت است.