سئوالات و مباحث WPF

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنون استاد . :rose:
فایل کامل کد را در زیر پیوست میکنم .

سلامی مجدد استاد .
همچنین استاد در بخشی از ControlTemplate.Triggers ئه مربوط به ComboBox نوشته :

XML:
                                <Trigger Property="IsGrouping" Value="true">
                                    <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                                </Trigger>

اما ComboBox که پروپرتی ای بنام ScrollViewer نداره .
همچنین توی توضیحات ScrollViewer.CanContentScroll هم نوشته نیست که Attached Property هست .
پس این پروپرتیِ ScrollViewer.CanContentScroll که نوشت ، چی هه و عضو چی هست که میتونه بهش دسترسی داشته باشه؟

راستی استاد ، Attached Property ها را از کجا میشه تشخیص داد که کدوم ها هستن؟
بجز اینکه در intellisense بنویسیم و لیست کنه . توی توضیحات سایت مایکروسافت هم Attached Property ها را براش جدول درست نکردن . صرفا توی توضیحات Remark اون هم در لا به لاش انگار اشاره میکنن .
بجز این دو روش ، روش دیگه ای برای فهمیدن اینکه یه پروپرتی ، Attached Property هست یا نه ، هست؟

خیلی ممنون .
 

the_king

مدیرکل انجمن
خیلی ممنون استاد . :rose:
فایل کامل کد را در زیر پیوست میکنم .
مشکلی نداره، شما یک SimpleComboBox ای تعریف کرده اید که اگر IsEnabled اش False شد Foreground اش Blue بشه و یک myComboBox ای بر اساس این SimpleComboBox توصیف کرده اید که میخواهید حتما "Foreground="White باشه. مشابه مثال پست 218 که Width رو هم در Setter ئه Style مشخص کرده بودید و هم در توصیف خود المنتی که از اون Style استفاده می کنه.

استاد ، من Ctrl+M+L را در قسمت کدنویسی میزنم و کدها همه collapse و جمع میشن .
حالا در ویژال استودیو راهی نداره که حالا اگه بخوایم فقط یه تَگ از کد را تا آخر باز کنیم ، این کار را بتونیم فقط برای اون بخش و تگ انجام بدیم؟
چون تگ های template معمولا خیلی بزرگن و هر بار که وارد ویژال استودیو میشیم ، وقت میبره تا تگ هاش را تا آخرِ اون تگ ، expand کنیم .

البته منظورم این نیست که کل کدها را expand کنیم . چون اون جوری بخاطر زیاد بودن کد ، اسکرول کردن سخت میشه .
کلید میانبر یا چیزی نیست که فقط اون تگ و بخشی که میخوایم را expand کنیم؟
اگر منظورتون رو درست متوجه شده باشم برای اون مجموعه region تعریف می کنید تا بصورت یک ناحیه collapse / expand بشه.
بخش XAML #region support رو ببینید.

منظورم اینه که استاد مثلا من قصد دارم برم برنامه نویسی موبایل را یاد بگیرم .
اول باید سیستم عامل ام را مشخص کنم . اندروید (با زامارین یا حتی android studio) یا windows core os .
شناخت بسیار کمی از اندروید دارم . پس شناخت بیشتر روی سیستم عامل اندروید و یادگیری تکنولوژی زامارین و کار کردن با api های اندروید ، یه زمان قابل توجهی را ازم میگیره .

اما بیاد و سال های بعد ، windows core os ، در حد اندروید استودیو ، کاربر داشت . یعنی مثلا 40 درصد موبایل ها ، اندروید نصب کردن و 40 درصد دیگه شون windows core os و 20 درصد هم بقیه ی سیستم عامل را .

خوب در این صورت ، از همین الان کوچ کردن به سمت .net core و uwp ، خیلی خیلی از هر جهت به نفع مه . چون هم با نوشتن یک برنامه ، در همه ی سیستم عامل های windows core os (از pc تا موبایل و ...) اجرا میشن که این مزیت بسیار بزرگی هست .
مزیت دیگه اش برام اینه که من به سیستم عامل ویندوز ، خیلی اطلاعات بیشتر و مسلط تر از اندروید هستم و نیازی نیست وقتم را صرف یادگیری بخش هایی از سیستم عامل اندروید که به برنامه نویسی انروید مرتبط هه کنم (از api های اندروید گرفته تا هر سرویس و چیزهای دیگه) .
مزیت بعدیش اینه که کوچ کردن از wpf به دات net core یا به uwp ، علی الظاهر باید خیلی راحت تر از یادگیری تکنولوژی هایی مثل زامارین و api های اندروید و ... باشه .

کلا از هر نظر به نفع مه که برنامه ام را تحت ویندوز بسازم (اگه بدونم windows core os ، حتی موفقیت نسبی داره . مثلا 50 درصد موبایل ها در سال های آینده ، اندروید و 30 درصد ، windows core os را نصب میکنن ، باز هم به نفع مه . یعنی کلا این سیستم عامل ، به یه موفقیت نسبی ، نسبت به الانش دست پیدا میکنه) .
شرایط رو بر فقط و فقط بر اساس توان و امکانات خودتون بسنجید، فرض کنید شما یک لیوان آب دست تونه، توان برداشت تون از منبع آب اندازه همون لیوان ئه، چه منبع روبروتون چشمه باشه و چه تانکر آب و چه یک پارچ آب به هر حال از اون منبع اندازه حجم یک لیوان آب نصیب شما میشه، نه بیشتر. برداشت آب از پارچ آب ساده تر ئه؟ اگر هست چه مزیتی داره که سراغ تانکر آب برید؟ شما به هر حال همونقدر آب گیرتون میاد.
شما می خواهید یک نرم افزار رو با ایده ای که دارید طراحی کنید، سردرگم این موندید که در بستر کدوم پلتفرم باشه؟ در پلتفرمی که خودتون راحت هستید. به همین سادگی. به این فکر می کنید که هر پلتفرم چقدر کاربر داره؟ واقع گرا باشید، توان و ظرفیت فروش شرکت های چند صد میلیارد دلاری رو بذارید کنار، مواردی که شما رو محدود می کنه هر چیزی هست بجز موفقیت پلتفرم، ظرفیت پلتفرم برای شما دست نیافتنی است چه برسه به اینکه محدود کننده باشه.

فرض کنیم در یک پلتفرم برای اون نرم افزار پتانسیل 500 میلیون کاربر باشه و در یک پلتفرم دیگه 50 میلیون کاربر. اما کلا توان و بضاعت شما در بازاریابی و فروش نرم افزار مگه چقدر ئه؟ چقدر میتوانید برای پشتیبانی هزینه کنید؟ یک میلیون کاربر رو می توانید پوشش بدید؟ اصلا کار راحتی نیست، ولی فرض کنیم همون یک میلیون کاربر. وقتی میدونید که بزرگی بازار فروش تون خیلی کوچکتر از گستردگی پوشش پلتفرم های متفاوت ئه، دیگه اهمیتی نداره که کدوم پلتفرم دست بالا رو داره. بلندپروازی خوبه ولی رویا پردازی نه. نهایت سهم برنامه نویسان مستقل و شرکت های کوچک با سرمایه اندک اندازه همون لیوان ئه، خیلی هنر کنند و موفق باشند همون لیوان شون رو پر می کنند. این لیوان رو در هر پلتفرمی میشه پر کرد.
 

the_king

مدیرکل انجمن
سلامی مجدد استاد .
همچنین استاد در بخشی از ControlTemplate.Triggers ئه مربوط به ComboBox نوشته :

XML:
                                <Trigger Property="IsGrouping" Value="true">
                                    <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
                                </Trigger>

اما ComboBox که پروپرتی ای بنام ScrollViewer نداره .
همچنین توی توضیحات ScrollViewer.CanContentScroll هم نوشته نیست که Attached Property هست .
پس این پروپرتیِ ScrollViewer.CanContentScroll که نوشت ، چی هه و عضو چی هست که میتونه بهش دسترسی داشته باشه؟
XAML مستقیما با مشخصه ها در ارتباط نیست، از DependencyProperty استفاده میشه که ذاتا پویا است. در بعضی رخداد ها مثلا هنگامی که Template بر المنت ای اعمال میشه فرصت برای اتصال DependencyProperty به مشخصه های اشیاء هست، یعنی الزامی نیست که حتما از ابتدا موقع توصیف در XAML اشیاء مربوطه شناسایی شده باشن. بر اساس روالی که برای کلاس نوشته شده میتونه اشیاء ای رو در موقع مناسب پیدا کنه و به DependencyProperty ربط بده. به اون ScrollViewer ای که با نام PART_ContentHost توصیف شده توجه کنید.

راستی استاد ، Attached Property ها را از کجا میشه تشخیص داد که کدوم ها هستن؟
بجز اینکه در intellisense بنویسیم و لیست کنه . توی توضیحات سایت مایکروسافت هم Attached Property ها را براش جدول درست نکردن . صرفا توی توضیحات Remark اون هم در لا به لاش انگار اشاره میکنن .
بجز این دو روش ، روش دیگه ای برای فهمیدن اینکه یه پروپرتی ، Attached Property هست یا نه ، هست؟
خیلی ممنون .
نشونه واضحی دارند، یک Attached Property در واقع تعریف مشخصه رو نداره، یعنی فرضا اگر Canvas.Left رو در نظر بگیرید اصلا مشخصه Left در کلاس تعریف نشده، DependencyProperty ای با نام LeftProperty هست ولی مشخصه Left نیست. بجاش با متد هایی برای get و set کردن مقدار ارتباط داره که اسمشون با نام مشخصه هماهنگ ئه. اگر دیدید که در کلاس DependencyProperty ای هست ولی مشخصه متناظر اش نیست، به احتمال زیاد Attached Property است. اگر در کد DependencyProperty.RegisterAttached یا DependencyProperty.RegisterAttachedReadOnly باشه، دیگه مطمئن می شوید که اینطوره چون اتصال مشخصه الحاقی توسط اونها است.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
مشکلی نداره، شما یک SimpleComboBox ای تعریف کرده اید که اگر IsEnabled اش False شد Foreground اش Blue بشه و یک myComboBox ای بر اساس این SimpleComboBox توصیف کرده اید که میخواهید حتما "Foreground="White باشه. مشابه مثال پست 218 که Width رو هم در Setter ئه Style مشخص کرده بودید و هم در توصیف خود المنتی که از اون Style استفاده می کنه.

خیلی ممنون استاد . :rose:
آها ، چون توی myComboBox مقدار Foreground را ست کردم ، پس توی خودِ Template نمیشه مجددا این پروپرتی را ست کرد. درسته؟
البته قبلا گفته بودین اما کد که پیچیده میشه ، قاتی میکنم . :green:

اگر منظورتون رو درست متوجه شده باشم برای اون مجموعه region تعریف می کنید تا بصورت یک ناحیه collapse / expand بشه.
بخش XAML #region support رو ببینید.

به region احتیاجی ندارم .
اون outline ها را انجام دادم ولی اون چیزی که میخواستم (expand کردن یک تگ تا انتهاش) ، نشد .

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

فرض کنیم در یک پلتفرم برای اون نرم افزار پتانسیل 500 میلیون کاربر باشه و در یک پلتفرم دیگه 50 میلیون کاربر. اما کلا توان و بضاعت شما در بازاریابی و فروش نرم افزار مگه چقدر ئه؟ چقدر میتوانید برای پشتیبانی هزینه کنید؟ یک میلیون کاربر رو می توانید پوشش بدید؟ اصلا کار راحتی نیست، ولی فرض کنیم همون یک میلیون کاربر. وقتی میدونید که بزرگی بازار فروش تون خیلی کوچکتر از گستردگی پوشش پلتفرم های متفاوت ئه، دیگه اهمیتی نداره که کدوم پلتفرم دست بالا رو داره. بلندپروازی خوبه ولی رویا پردازی نه. نهایت سهم برنامه نویسان مستقل و شرکت های کوچک با سرمایه اندک اندازه همون لیوان ئه، خیلی هنر کنند و موفق باشند همون لیوان شون رو پر می کنند. این لیوان رو در هر پلتفرمی میشه پر کرد.

خوب هر چی تعداد کاربران سیستم عامل ، بیشتر باشه ، قطعا به نفع برنامه نویس هست . اگه سیستم عاملی 50 میلیون کاربر داشته باشه (نسبت به اونی که 500 میلیون داره) ، همه ی اون 50 میلیون کاربر که توی ایران نیستن و همه ی اونهایی که توی ایران هستند هم که نیاز به برنامه ی ای که مینویسیم ندارن و همه ی اون کسایی که نیاز دارن معلوم نیست اصلا اون برنامه را بتونن تهیه کنن یا نه و اون هایی هم که تهیه میکنن ، معلوم نیست که برنامه های رقیب مون را تهیه میکنن یا برنامه ی ما را .
پس قطعا اگه میزان استفاده ی سیستم عاملی ، 10 برابر بیشتر از یه سیستم عامل دیگه باشه ، احتمال اینکه کاربر اون سیستم عامل نسبت به سیستم عاملی که 10 برابر کاربر کمتری داره ، برنامه ی ما را تهیه کنه هم 10 برابر (یا حداقل چند برابر) میشه .


XAML مستقیما با مشخصه ها در ارتباط نیست، از DependencyProperty استفاده میشه که ذاتا پویا است. در بعضی رخداد ها مثلا هنگامی که Template بر المنت ای اعمال میشه فرصت برای اتصال DependencyProperty به مشخصه های اشیاء هست، یعنی الزامی نیست که حتما از ابتدا موقع توصیف در XAML اشیاء مربوطه شناسایی شده باشن. بر اساس روالی که برای کلاس نوشته شده میتونه اشیاء ای رو در موقع مناسب پیدا کنه و به DependencyProperty ربط بده. به اون ScrollViewer ای که با نام PART_ContentHost توصیف شده توجه کنید.

اون ScrollViewer ای که نام PART_ContentHost داره ، توی توی یه ControlTemplate ئه دیگه ای با کلید TextBoxOfComboBoxTemplate هست .
اما اون کدِ :

XML:
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>

که توی Style ئه SimpleComboBox هست . این دو تا که دو اسکوپِ متفاوت هستند و به هم دسترسی ندارند . TemplateBinding و کلا بایندینگ هم انجام ندادیم . پس چجوری میشه از درونِ Style ئه SimpleComboBox ، به اون ScrollViewer ئه درون TextBoxOfComboBoxTemplate دسترسی داشت؟
یه کم درباره ی این نوعِ دسترسی ، توضیح میدین؟

نشونه واضحی دارند، یک Attached Property در واقع تعریف مشخصه رو نداره، یعنی فرضا اگر Canvas.Left رو در نظر بگیرید اصلا مشخصه Left در کلاس تعریف نشده، DependencyProperty ای با نام LeftProperty هست ولی مشخصه Left نیست. بجاش با متد هایی برای get و set کردن مقدار ارتباط داره که اسمشون با نام مشخصه هماهنگ ئه. اگر دیدید که در کلاس DependencyProperty ای هست ولی مشخصه متناظر اش نیست، به احتمال زیاد Attached Property است. اگر در کد DependencyProperty.RegisterAttached یا DependencyProperty.RegisterAttachedReadOnly باشه، دیگه مطمئن می شوید که اینطوره چون اتصال مشخصه الحاقی توسط اونها است.

خیلی ممنون استاد .
 

the_king

مدیرکل انجمن
خوب هر چی تعداد کاربران سیستم عامل ، بیشتر باشه ، قطعا به نفع برنامه نویس هست . اگه سیستم عاملی 50 میلیون کاربر داشته باشه (نسبت به اونی که 500 میلیون داره) ، همه ی اون 50 میلیون کاربر که توی ایران نیستن و همه ی اونهایی که توی ایران هستند هم که نیاز به برنامه ی ای که مینویسیم ندارن و همه ی اون کسایی که نیاز دارن معلوم نیست اصلا اون برنامه را بتونن تهیه کنن یا نه و اون هایی هم که تهیه میکنن ، معلوم نیست که برنامه های رقیب مون را تهیه میکنن یا برنامه ی ما را .
پس قطعا اگه میزان استفاده ی سیستم عاملی ، 10 برابر بیشتر از یه سیستم عامل دیگه باشه ، احتمال اینکه کاربر اون سیستم عامل نسبت به سیستم عاملی که 10 برابر کاربر کمتری داره ، برنامه ی ما را تهیه کنه هم 10 برابر (یا حداقل چند برابر) میشه .
شما هر طوری که مایل هستید فکر کنید، فقط در مورد موضوعی که خودتون رو صاحب نظر میدونید از من نظر و راهنمایی نخواهید. استیو بالمر اینطور در مورد تجارت قاطعانه نسبت ارائه نمیده که شما می دهید.

اون ScrollViewer ای که نام PART_ContentHost داره ، توی توی یه ControlTemplate ئه دیگه ای با کلید TextBoxOfComboBoxTemplate هست .
اما اون کدِ :

XML:
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>

که توی Style ئه SimpleComboBox هست . این دو تا که دو اسکوپِ متفاوت هستند و به هم دسترسی ندارند . TemplateBinding و کلا بایندینگ هم انجام ندادیم . پس چجوری میشه از درونِ Style ئه SimpleComboBox ، به اون ScrollViewer ئه درون TextBoxOfComboBoxTemplate دسترسی داشت؟
یه کم درباره ی این نوعِ دسترسی ، توضیح میدین؟
SimpleComboBox نمیدونه که PART_ContentHost کجاست ولی TextBoxOfComboBoxTemplate که میدونه داره روی کدوم TextBox اعمال میشه.
وقتی TextBoxOfComboBoxTemplate ئه که ScrollViewer ئه داخلش توصیف شده روی المنت TextBox اعمال میشه، کد داخل ScrollViewer که مربوط به زمان اعمال شدن روی Template ئه رو اجرا می کنه. که در اون کدی نوشته شده که از طریق DependencyProperty مشخصه CanContentScroll رو متصل می کنه به همون شیء، یعنی PART_ContentHost. برای همین وقتی ScrollViewer.CanContentScroll در Style ئه میخواد مقدار مشخصه رو false کنه، DependencyProperty ئه وصل شده به PART_ContentHost و مقدار CanContentScroll اون PART_ContentHost است که false میشه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
وقتی TextBoxOfComboBoxTemplate ئه که ScrollViewer ئه داخلش توصیف شده روی المنت TextBox اعمال میشه، کد داخل ScrollViewer که مربوط به زمان اعمال شدن روی Template ئه رو اجرا می کنه. که در اون کدی نوشته شده که از طریق DependencyProperty مشخصه CanContentScroll رو متصل می کنه به همون شیء، یعنی PART_ContentHost.

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

the_king

مدیرکل انجمن
خیلی ممنون استاد (همچنین از بقیه ی جملات تون) .
من این تیکه را خوب متوجه نشدم . مخصوصا تیکه ی بولد شده را متوجه نشدم .
کلا الان من اگه بخوام از یه اسکوپ ، به یه اسکوپ دیگه که بهش دسترسی ندارم ، دسترسی پیدا کنم (مثل همین قضیه) ، چی کار باید کنم؟
این البته مشکل شما نیست، طراحان ScrollViewer بودند که می بایست مشکل شون رو حل میکردند، شما قراره از ScrollViewer استفاده کنید، نه اینکه برای دسترسی به CanContentScroll دنبال راه حل باشید. اما اگر بخواهید روال مشابهی رو کد نویسی کنید باید نحوه طراحی و کد نویسی کنترل های WPF رو یاد بگیرید. مثلا کد داخل کلاس ScrollViewer رو بررسی کنید. ببینید در متد OnPreApplyTemplate چیکار کرده.
متد هایی مثل FrameworkElement.OnApplyTemplate و FrameworkElement.OnStyleChanged رو مطالعه کنید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
این البته مشکل شما نیست، طراحان ScrollViewer بودند که می بایست مشکل شون رو حل میکردند، شما قراره از ScrollViewer استفاده کنید، نه اینکه برای دسترسی به CanContentScroll دنبال راه حل باشید. اما اگر بخواهید روال مشابهی رو کد نویسی کنید باید نحوه طراحی و کد نویسی کنترل های WPF رو یاد بگیرید. مثلا کد داخل کلاس ScrollViewer رو بررسی کنید. ببینید در متد OnPreApplyTemplate چیکار کرده.
متد هایی مثل FrameworkElement.OnApplyTemplate و FrameworkElement.OnStyleChanged رو مطالعه کنید.

ممنون استاد .
آها . یعنی کدهای داخل این متدها باعث شدن که این دسترسی را به پروپرتیِ CanContentScroll ئه ScrollViewer ، از یک اسکوپ دیگه بشه داشت؟
یعنی بصورت پیش فرض اگه کدهایی مثل اون متدها پیاده سازی نشن ، همچین دسترسی ای امکان پذیر نیست؟
 

the_king

مدیرکل انجمن
ممنون استاد .
آها . یعنی کدهای داخل این متدها باعث شدن که این دسترسی را به پروپرتیِ CanContentScroll ئه ScrollViewer ، از یک اسکوپ دیگه بشه داشت؟
یعنی بصورت پیش فرض اگه کدهایی مثل اون متدها پیاده سازی نشن ، همچین دسترسی ای امکان پذیر نیست؟
نباید اصلا همچین دسترسی ای نیاز باشه، اگر کلاس ها رو بررسی کنید می بینید که الان هم اون XAML هم همچین دسترسی ای ایجاد نکرده. اینکه CanContentScroll ئه false میشه به معنی دسترسی به PART_ContentHost که نیست، دسترسی به CanContentScrollProperty ئه که اونم public static ئه. اون فیلد های DependencyProperty که XAML بهشون دسترسی داره از نوع static هستند، static که شیء نداره که مشکل دسترسی داشته باشه.

و اینها مربوط به طراحی داخل WPF ئه، نه برنامه نویسی تحت WPF. ربطی به XAML نداره، مربوط به نحوه کار ScrollViewer ئه. اگر جایی همچین نیازی رو احساس بکنید که از فلان اسکوپ به اسکوپ دیگری دسترسی باشه، معلومه که کار تون اشتباه ئه، دارید کاری رو به روش نادرستی انجام می دهید، نه اینکه یک چیزی کم ئه. مثل اینه که بگیم چطور for رو بنویسیم که اول دستورات بعد از for رو اجرا کنه و بعد دستورات داخل for. اگر همچین نیازی پیدا کردیم روال مون اشتباه بوده، با منطق درست نباید همچین نیازی باشه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلیل ممنون استاد .
استاد در کد زیر :

XML:
        <ComboBox x:Name="myComboBox2" HorizontalAlignment="Left" Height="28" Margin="9,206,0,0" VerticalAlignment="Top" Width="202" SelectedIndex="0">
            <!--<ComboBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <TextBlock Text="{Binding Source=}"/>
                    </Grid>
                </DataTemplate>
            </ComboBox.ItemTemplate>-->

            <ComboBox.Resources>
                <x:Array x:Key="stringArray" Type="System:String">
                    <System:String>salam</System:String>
                    <System:String>khobi?</System:String>
                </x:Array>
            </ComboBox.Resources>
            
            <ComboBox.Items>
                
                <!--<Binding Source="{DynamicResource stringArray}" Path="Items"/>-->
            </ComboBox.Items>
        </ComboBox>

اگه بخوام ComboBox.Items را به اون stringArray ، بایند کنم یا کلا به هر روشی ، منبعِ اون پروپرتیِ Items را بخوام آرایه ی stringArray بگیرم ، چی باید بنویسم؟

و مهمتر اینکه اگه بخوام منبعِ پروپرتیِ Text ئه TextBlock ، همون آرایه باشه (جوری که همه ی اعضای آرایه را در اون بیاره و لیست کنه) یا اینکه منبعش ، پروپرتی ComboBox.Items مون باشه ، چی باید بنویسم؟

استاد ، با توجه به اینکه برای یه کمبوباکس ام ، پروپرتی Template را ست کردم ، حالا اگه بخوام در کنارش ، دونه دونه ی اعضای popup از کمبوباکس ام (همون لیستی که با کلیک روی کمبوباکس باز میشه) را کنترل کنم (رنگ پشت زمینه ی اعضا و رنگ متن و ...) ، و همچنین کنترل رنگ اعضایی که کاربر موس را روش میبره را کنترل و شخصی سازی کنم ، باید از پروپرتیِ ComboBox.ItemTemplate استفاده کنم یا از ComboBox.ItemContainerStyle ؟
دقت کنید که از پروپرتی Template هم استفاده کردم .

تشکر استاد .
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلیل ممنون استاد .
استاد در کد زیر :

XML:
        <ComboBox x:Name="myComboBox2" HorizontalAlignment="Left" Height="28" Margin="9,206,0,0" VerticalAlignment="Top" Width="202" SelectedIndex="0">
            <!--<ComboBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <TextBlock Text="{Binding Source=}"/>
                    </Grid>
                </DataTemplate>
            </ComboBox.ItemTemplate>-->

            <ComboBox.Resources>
                <x:Array x:Key="stringArray" Type="System:String">
                    <System:String>salam</System:String>
                    <System:String>khobi?</System:String>
                </x:Array>
            </ComboBox.Resources>
         
            <ComboBox.Items>
             
                <!--<Binding Source="{DynamicResource stringArray}" Path="Items"/>-->
            </ComboBox.Items>
        </ComboBox>

اگه بخوام ComboBox.Items را به اون stringArray ، بایند کنم یا کلا به هر روشی ، منبعِ اون پروپرتیِ Items را بخوام آرایه ی stringArray بگیرم ، چی باید بنویسم؟

استاد ، جواب سئوال اول و دوم را تا حدودی (نه کامل) پیدا کردم . اما جواب اون سئوال آخر را هنوز متوجه نشدم .
برای سئوال اول و دوم ، میشه کد را بصورت زیر نوشت :

XML:
        <ComboBox x:Name="myComboBox2"  HorizontalAlignment="Left" Height="28" Margin="9,206,0,0" VerticalAlignment="Top" Width="202" SelectedIndex="0">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <TextBlock Foreground="Red" Text="{Binding }"/>
                    </Grid>
                </DataTemplate>
            </ComboBox.ItemTemplate>

            <ComboBox.DataContext>
                <x:Array Type="System:String">
                    <System:String>salam</System:String>
                    <System:String>khobi?</System:String>
                </x:Array>
            </ComboBox.DataContext>

            <ComboBox.ItemsSource>
                <Binding/>
            </ComboBox.ItemsSource>
        </ComboBox>

که DataContext جایی هه که وقتی شی و کدی نوشتیم ، به عنوان منبعِ binding هایی که در اون شی و تگ (تگ ComboBox) قراره انجام بشه را قبول میکنه . چون به عنوان منبعِ binding شناسایی میکنه ، لازم نیست که binding هایی که در اون شی و تگ انجام میدیم ، پروپرتیِ Source ئه اون Binding را مشخص کنیم .
همچنین برای قضیه ی bind کردنِ Text ئه TextBlock ، قضیه اش همینطوره .

اما نمیدونم وقتی در کد بالا که Binding بکار بردیم ، بخوایم معادلش ، پروپرتیِ Path را مشخص کنیم ، چی باید بنویسیم؟
همچنین اگه بخوایم فقط یک المنت از اون آرایه را در پروپرتیِ Path مشخص کنیم ، چی باید بنویسیم؟
همینطور استاد ، سئوال آخری پست قبلی را هم بی زحمت جواب میدین؟

ببخشید خیلی مزاحم تون همیشه هستم
تشکر :rose:
 
آخرین ویرایش:

the_king

مدیرکل انجمن
استاد ، جواب سئوال اول و دوم را تا حدودی (نه کامل) پیدا کردم . اما جواب اون سئوال آخر را هنوز متوجه نشدم .
برای سئوال اول و دوم ، میشه کد را بصورت زیر نوشت :

XML:
        <ComboBox x:Name="myComboBox2"  HorizontalAlignment="Left" Height="28" Margin="9,206,0,0" VerticalAlignment="Top" Width="202" SelectedIndex="0">
            <ComboBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <TextBlock Foreground="Red" Text="{Binding }"/>
                    </Grid>
                </DataTemplate>
            </ComboBox.ItemTemplate>

            <ComboBox.DataContext>
                <x:Array Type="System:String">
                    <System:String>salam</System:String>
                    <System:String>khobi?</System:String>
                </x:Array>
            </ComboBox.DataContext>

            <ComboBox.ItemsSource>
                <Binding/>
            </ComboBox.ItemsSource>
        </ComboBox>

که DataContext جایی هه که وقتی شی و کدی نوشتیم ، به عنوان منبعِ binding هایی که در اون شی و تگ (تگ ComboBox) قراره انجام بشه را قبول میکنه . چون به عنوان منبعِ binding شناسایی میکنه ، لازم نیست که binding هایی که در اون شی و تگ انجام میدیم ، پروپرتیِ Source ئه اون Binding را مشخص کنیم .
همچنین برای قضیه ی bind کردنِ Text ئه TextBlock ، قضیه اش همینطوره .

اما نمیدونم وقتی در کد بالا که Binding بکار بردیم ، بخوایم معادلش ، پروپرتیِ Path را مشخص کنیم ، چی باید بنویسیم؟
همچنین اگه بخوایم فقط یک المنت از اون آرایه را در پروپرتیِ Path مشخص کنیم ، چی باید بنویسیم؟
همینطور استاد ، سئوال آخری پست قبلی را هم بی زحمت جواب میدین؟

ببخشید خیلی مزاحم تون همیشه هستم
تشکر :rose:
Binding باید بر اساس یک DependencyProperty کار کنه، Items به DependencyProperty متصل نیست که بخواهید به چیزی متصلش کنید.
بدون کد نویسی یک افزونه جدید یا تعریف مبدل یا کد نویسی در کلاس المنت نمی توانید مستقیما با XAML مجموعه string رو تحویل یک مشخصه ای مثل Items کنید که DependencyProperty نداره.

اگر بخواهید ظاهر آیتم ها رو تغییر بدهید از ItemTemplate هم در کنار ItemContainerStyle استفاده خواهید کرد ولی صرفا اگر بخواهید مشخصه های آیتم ها رو با حفظ همون ظاهر پیشفرض بر اساس مواردی تغییر بدهید فقط ItemContainerStyle رو سفارشی می کنید.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
خیلی ممنون استاد .
الاناگه بخوایم کدی که در پست شماره ی ۳۵۱ دادم را ، مقدارِ پروپرتیِ Source و همچنین Path را مشخص کنیم تا مثل همون کد (که در پست ۳۵۱ دادم) ، کار کنه ، مقادیرِ این پروپرتی ها را چی باید تعیین کنیم؟
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
الاناگه بخوایم کدی که در پست شماره ی ۳۵۱ دادم را ، مقدارِ پروپرتیِ Source و همچنین Path را مشخص کنیم تا مثل همون کد (که در پست ۳۵۱ دادم) ، کار کنه ، مقادیرِ این پروپرتی ها را چی باید تعیین کنیم؟
من نمیدونم شما در مورد کدوم DependencyProperty سوال می کنید. Source و Path برای داخل Binding ئه، و حالا می خواهید این Binding رو برای Bind کردن به کدوم DependencyProperty استفاده کنید؟
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
من نمیدونم شما در مورد کدوم DependencyProperty سوال می کنید. Source و Path برای داخل Binding ئه، و حالا می خواهید این Binding رو برای Bind کردن به کدوم DependencyProperty استفاده کنید؟

خودمم نمیدونم استاد .
دقیقا سئوالم هم ، همینه .
اینکه کد شماره ی ۳۵۱ که کار میکنه و پروپرتی های Source و Path اش مشخص نشدن ، پس بصورت بصورت پیش فرض در اون کد ، چه مقداری دارن؟
نمیشه که مقدار نداشته باشن ؟ میشه مگه؟

مثلا متغییرهای سراسریِ nullable را که در سی شارپ ، مقداری ندیم ، مقدار پیش فرض اش null هست ، پس این دو پروپرتی ، چه مقداری در اون کد دارن؟
 

the_king

مدیرکل انجمن
خودمم نمیدونم استاد .
دقیقا سئوالم هم ، همینه .
اینکه کد شماره ی ۳۵۱ که کار میکنه و پروپرتی های Source و Path اش مشخص نشدن ، پس بصورت بصورت پیش فرض در اون کد ، چه مقداری دارن؟
نمیشه که مقدار نداشته باشن ؟ میشه مگه؟
سوال جدید تون اصلا شباهتی به سوال قبلی نداره ها.
اگر میخواهید بدونید مقدار پیشفرض مشخصه ها چیه باید به کجا مراجعه کنید؟ نگید که نمیدونید. به مستنداتش دیگه.
null.png
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
سوال جدید تون اصلا شباهتی به سوال قبلی نداره ها.
اگر میخواهید بدونید مقدار پیشفرض مشخصه ها چیه باید به کجا مراجعه کنید؟ نگید که نمیدونید. به مستنداتش دیگه.
مشاهده پیوست 113566

خیلی ممنون استاد .
نه ، سئوالم این نبود .
نگاه کنید من در پست ۳۵۱ ، برای بایند کردن ، فقط تگِ <Bind> را دادم و کد ، کار میکنه . درسته؟
خوب ، این تگ ، یه مقدار برای پروپرتیِ Path و یه مقدار هم برای پروپرتیِ Source لازم داره برای کار کردن . قطعا مفسر xaml در wpf ، در اون تگ ، خودش یه مقداری رو به اون دو تا پروپرتی داد که داره کار میکنه (هر چند ما بصورت صریح نداده باشیم) . درسته؟
میخوام بدونم مقدار این پروپرتی ها که مفسر xaml در wpf بصورت ضمنی داد ، چه مقداری هه؟

ممنون استاد.
 

the_king

مدیرکل انجمن
خیلی ممنون استاد .
نه ، سئوالم این نبود .
نگاه کنید من در پست ۳۵۱ ، برای بایند کردن ، فقط تگِ <Bind> را دادم و کد ، کار میکنه . درسته؟
خوب ، این تگ ، یه مقدار برای پروپرتیِ Path و یه مقدار هم برای پروپرتیِ Source لازم داره برای کار کردن.
تگ Bind نه، تگ Binding. بر چه اساسی نیازش رو شناسایی می کنید؟ شما که روال داخل Binding رو تجزیه و تحلیل نکرده اید. با حدس زدن که نمی توانید تشخیص بدهید که برای کار کردنش مشخص شدن مقدار مشخصه ها لازم است یا نیست.
اگه توضیحات Binding.Path رو در سایت مایکروسافت مطالعه کنید می بینید که شرح داده که مورد خلاصه شده ای مثل "Text="{Binding} چه منبعی رو بکار می بره.
قطعا مفسر xaml در wpf ، در اون تگ ، خودش یه مقداری رو به اون دو تا پروپرتی داد که داره کار میکنه (هر چند ما بصورت صریح نداده باشیم) . درسته؟
قطعا یعنی حتمی، یعنی صد درصد، بعد آخرش می پرسید درسته؟ چطوری میتونه گزاره تون هم قاطعانه باشه و هم روی درستی اش تردید داشته باشید.
رو چه حسابی تحلیل می کنید که قطعا فلان باید باشه؟
میخوام بدونم مقدار این پروپرتی ها که مفسر xaml در wpf بصورت ضمنی داد ، چه مقداری هه؟
ممنون استاد.
مقدار ضمنی ای در کار نیست، برای مشخصه ای مقداری تعیین نکرده اید و با همون مقدار پیشفرض میمونه.
مفسر نه، کامپایلر. کامپایلر کد XAML شما رو همانطور که هست ترجمه می کنه، نه یک نقطه ازش کم میشه و نه اضافه میشه.
 

SajjadKhati

کاربر فعال <A href="http://forum.majidonline.com/f
تگ Bind نه، تگ Binding. بر چه اساسی نیازش رو شناسایی می کنید؟ شما که روال داخل Binding رو تجزیه و تحلیل نکرده اید. با حدس زدن که نمی توانید تشخیص بدهید که برای کار کردنش مشخص شدن مقدار مشخصه ها لازم است یا نیست.
اگه توضیحات Binding.Path رو در سایت مایکروسافت مطالعه کنید می بینید که شرح داده که مورد خلاصه شده ای مثل "Text="{Binding} چه منبعی رو بکار می بره.

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

مقدار ضمنی ای در کار نیست، برای مشخصه ای مقداری تعیین نکرده اید و با همون مقدار پیشفرض میمونه.
مفسر نه، کامپایلر. کامپایلر کد XAML شما رو همانطور که هست ترجمه می کنه، نه یک نقطه ازش کم میشه و نه اضافه میشه.

ممنون استاد .
پس بصورت پیش فرض ، اگه فقط تگ <Binding> را مشخص کنیم ، مقدار Path ، فقط یک نقطه و بصورتِ Path="." هست .
در کد زیر ، درست شد :

XML:
        <ComboBox x:Name="myComboBox2"  HorizontalAlignment="Left" Height="28" Margin="9,206,0,0" VerticalAlignment="Top" Width="202" SelectedIndex="0">
            <ComboBox.Resources>
                <x:Array x:Key="stringArray" Type="System:String">
                    <System:String>salam</System:String>
                    <System:String>khobi?</System:String>
                </x:Array>
            </ComboBox.Resources>

            <ComboBox.ItemsSource>
                <Binding Source="{StaticResource stringArray}"/>
            </ComboBox.ItemsSource>
        </ComboBox>

فکر میکردم StaticResource هم مثل DynamicResource ، باید target propery ، یه Dependency پروپرتی باشه . این طور نیست . اون محدودیت فقط برای DynamicResource هست .

همچنین با مقدار دادنِ Path ، داخل یک کلوشه و دادنِ اندیس آرایه ، اون عضو از آرایه ، داخل تمام آیتم های کمبوباکس قرار میگیره . مثلا در مثال بالا اگه Path="]0[" بدیم ، مقدار salam را برای هر کاراکتر ، در هر آیتمِ کمبوباکس میذاره .

همچنین در کد قبلی (پست 350) ، پروپرتیِ ComboBox.Items را مقداردهی و Bind کردم ، چون این پروپرتی ، DependencyProperty نیست ، ارور میداد و بجاش باید توسط پروپرتیِ ItemsSource (که DependencyProperty هست) ، Bind با StaticResource مون را انجام بدیم .

تشکر استاد .
 
آخرین ویرایش:

جدیدترین ارسال ها

بالا