PDA

View Full Version : آموزش: آموزش ساخت کنترل سفارشی



Mori Bone
سه شنبه 05 آبان 1394, 23:54 عصر
سلام دوستان. عزاداری هاتون مقبول درگاه حق انشالله. یاحسین شهید

خیلی وقت بود میخواستم این آموزشو قرار بدم متاسفانه وقت نشد و میدونم خیلیا ب این آموزش نیاز دارن.:بوس:
توی این اموزش قصد دارم باهم ی کنترل سفارشی درست کنیم با استفاده از WPF Custom Control Libraryها ک میتونید تفاوتشون رو با User Controlها با ی جستجوی کوچیک درک کنید.:چشمک:

این ابزار کاستوم کنترل دو بخش اصلی داره: یکی بخش کد و یکی xaml (طراحی).
در بخش طراحی برعکس UserControlها شما محیط طراحی ندارید(مانندطراحی استایل داخل ویژوال استدیو) و فقط با xaml سروکاردارید.(من با بلندBlend میونه خوشی ندارم خیلیها میدونن:خجالت:).
در محیط کد هم ک کدنویسی ب زبان سی شارپ یا وی بی رو انجام میدید.



آموزش ایجاد دکمه سفارشی با اسفاده از WPF Custom Control Library:

خب اول از همه پروژه ای ب اسم MyControl ایجاد میکنیم ک از نوع WPF Custom Control Libraryاست. خب الان باید شما داخل پروژه بخش های اصلی رو مشاهده کنید. بخش کد ک همون اول ب داخلش هدایت شدید و فایلی ب اسمه Generic.Xaml داخل پوشه Themes قرار داره ک کد های طراحی در اون جاس. خب فعلا با بخش کد کار داریم. ابتدا اسم کلاس رو ب NewButton تغییر بدید ک از System.Windows.Controls.Button ارث بری میکنه. به شکل زیر:
public class NewButton : System.Windows.Controls.Button

خب چند خط پایین تر با بلاک کدی روبرو میشیم ک نقش ارتباط بخش کد و طراحی رو داره:
static CustomControl1()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Cu stomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1))) ;
}

ک باید برخی بخش هاش با اسم کلاس یکی باشه، پس باید به کده زیر تغییر کنه:
static NewButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Ne wButton), new FrameworkPropertyMetadata(typeof(NewButton)));
}

حتما متن های طولامی کامنت شده رو مشاهده کردید ک یکسری توضیحات داره ک ازش میگذریم. اگه رو مختونه پاکشون کنید.:چشمک::گیج:


خب میریم سراغ فایل طراحی.
فایل generic.xaml داخل themes رو باز کنید. همونطور ک میبینید با ی ریسورس دیکشنری روبرو هستید ک کارش نگه داری استایل شماست. ک البته با بخش کد شما هماهنگه.
این جا خیلی تغییرات ایجاد میکنیم ولی فعلا فقط دو جا رو تغییر بدید. دو local:CustomControl1 وجود دارد ک باید ب local:NewButton تغییر کند. چرا؟ چون ما اسمه کلاس رو تغییر دادیم و باید بخش کد رو ب بخش طراحی معرفی و بشناسونیم.
همون طور ک مبینید استایلی ایجاد شده از نوع کلاس NewButton ک البته کلاسمون از کنترل باتن ارث بری کرده. پس ما باتنی ب اسمه NewButton رو تغییر میدیم. بعد از تغییرات F6 رو بزنید تا پروژه بیلد بشه.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyControl">
<Style
TargetType="{x:Type local:NewButton}">
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="{x:Type local:NewButton}">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">

</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>




خب این یک نمونه استایله ک من قبلا طاحی کزدم ک خیلی سادس:
<Style
TargetType="{x:Type local:NewButton}">

<Setter
Property='VerticalContentAlignment'
Value='Center' />
<Setter
Property='HorizontalContentAlignment'
Value='Center' />
<Setter
Property='BorderThickness'
Value='1' />
<Setter
Property='FontSize'
Value='15' />
<Setter
Property='Foreground'
Value='#2d2d30' />
<Setter
Property='BorderBrush'
Value='#a1a1a1' />
<Setter
Property='Background'>
<Setter.Value>
<LinearGradientBrush
EndPoint='0.5,1'
StartPoint='0.5,0'>
<GradientStop
Color='LightGray'
Offset='1' />
<GradientStop
Color='White' />
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="{x:Type local:NewButton}">
<Border
CornerRadius='4'
x:Name='border'
BorderBrush='{TemplateBinding BorderBrush}'
BorderThickness='{TemplateBinding BorderThickness}'
Background='{TemplateBinding Background}'
SnapsToDevicePixels='True'>
<ContentPresenter
x:Name='contentPresenter'
ContentTemplate='{TemplateBinding ContentTemplate}'
Content='{TemplateBinding Content}'
ContentStringFormat='{TemplateBinding ContentStringFormat}'
Focusable='False'
HorizontalAlignment='{TemplateBinding HorizontalContentAlignment}'
Margin='{TemplateBinding Padding}'
RecognizesAccessKey='True'
SnapsToDevicePixels='{TemplateBinding SnapsToDevicePixels}'
VerticalAlignment='{TemplateBinding VerticalContentAlignment}' />
</Border>
<ControlTemplate.Triggers>
<Trigger
Property='Button.IsDefaulted'
Value='True'>
<Setter
Property='BorderBrush'
TargetName='border'
Value='{DynamicResource {x:Static SystemColors.HighlightBrushKey}}' />
</Trigger>
<Trigger
Property='IsMouseOver'
Value='True'>
<Setter
Property='Background'
TargetName='border'>
<Setter.Value>
<LinearGradientBrush
EndPoint='0.5,1'
StartPoint='0.5,0'>
<GradientStop
Offset='1'
Color='White' />
<GradientStop
Color='LightGray' />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger
Property='IsPressed'
Value='True'>
<Setter
Property='Background'
TargetName='border'>
<Setter.Value>
<LinearGradientBrush
EndPoint='0.5,1'
StartPoint='0.5,0'>
<GradientStop
Color='LightGray'
Offset='1' />
<GradientStop
Color='White' />
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger
Property='IsEnabled'
Value='False'>

</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
این کد رو ب کل جایگزین استایل بخش طراحی بکنید.

خب کار دکمه تمومه و فقط میمونه چند تا توضیح پایانی.
اگه این دکمه داخل یوزرکنترل طراحی شده بود الان باید میرفتیم سراغه طراحی ایونت کلیک دکمه:عصبانی++:. میپرسید چرا اینجا همچین کاری نمیکنیم؟ چون اینجا کل کلاس از باتن ارث بری کرده و تمام مشخصه های یک باتن رو داره و شما از هر کنترلی ارث بری کنید تمام مشخصه های اون کنترل در دسترستونه بر عکس یوزر کنترل.البته یوزرکنترل اهدافش چیزه دیگه ایه نمیخوام خرابش کنم. یوزر کنترل در جای خودش استفاده بشه واقعا کار راه بنداز و عالیه.:قلب:


خب میریم سر استفاده از کنترلمون.
ابتدا با F6 پروژه رو بیلد کنید.داخل پروژه ای ک میخواید از این دکمه استفاده کنید بشید و روی پروژه راست کلیک کرده و Add Refrence رو بزنید. حالا داخل پروژه دکمه سفارشی به مسیر bin\debug بروید و کتابخونه ی MyControl رو ب پروژتون اضافه کنید.
حالا ب تگ Window کد زیر رو اضافه کنید:
clr-namespace:MyControl;assembly=MyControlحالا به جای استفاده از تگ
<Button></Button>
از
<MyControl:Button></MyControl:Button>
استفاده کنید با تمام امکانات دکمه قبلی ولی با ظاهری متفاوت.


بیشتر تمرین کنید با همه چی آشنا بشید. ایشالله پست بعدی یک کنترل Window رو سفارشی میکنیم:چشمک::بوس:

موفق باشید. در پناه حق

MMR_1234
چهارشنبه 06 آبان 1394, 06:39 صبح
با سپاس از آموزشتون
من مطابق اون اقدام کردم و فایلم رو ساختم اما نمیدونم چرا در زمان استفاده اون دکمه جدید رو نمیخونه
فایل رو پیوست کردم
سوالی هم داشتم اگر بخوام چند استایل مختلف درست کنم
میتونم برای هر استایل نام خاصی تعریف و با اون نام استایلم رو فراخوانی کنم یا در هر برنامه فقط یک استایل میشه تعریف کرد
از آموزشتون ممنونم

Mori Bone
چهارشنبه 06 آبان 1394, 11:02 صبح
با سپاس از آموزشتون
من مطابق اون اقدام کردم و فایلم رو ساختم اما نمیدونم چرا در زمان استفاده اون دکمه جدید رو نمیخونه
فایل رو پیوست کردم
سوالی هم داشتم اگر بخوام چند استایل مختلف درست کنم
میتونم برای هر استایل نام خاصی تعریف و با اون نام استایلم رو فراخوانی کنم یا در هر برنامه فقط یک استایل میشه تعریف کرد
از آموزشتون ممنونم
سلام من تو پسته اول حرف اول assembly رو بزرگ نوشتم برای همین ایراد گرفت. خطه زیر رو ب WpfApplication1 -> MainWindow اضافه کنید.
xmlns:MyControl="clr-namespace:MyControl;assembly=MyControl"

MMR_1234
چهارشنبه 06 آبان 1394, 13:59 عصر
دوست عزیز تغیری رو هم که فرمودین انجام دادم بازم مشکل داره
فایل و پیوست کردم
در ضمن برای تعریف چندیدن استایل تو یک کتابخانه جوابی ندادین
یک مشکل دیگه هم بوجود اومده اونم اینه که
در برنامه از کتابخانه کلید برای کاربری و استفاده از توابع اون استفاده شده حالا وقتی کلید جدید رو فراخوانی میکنی به هیچکدوم از اونا دسترسی نداره
با تشکر

MMR_1234
چهارشنبه 06 آبان 1394, 15:43 عصر
ببخشین
یک موضوع دیگه اگه بخوام از DLL ساخته شده در دیگر بنامه ها مثل WinForm استفاده کنم میسر هست
و تعریف اون چه جوری میشه؟؟؟؟؟؟:افسرده:

Mori Bone
چهارشنبه 06 آبان 1394, 22:18 عصر
136331
دوست عزیز تغیری رو هم که فرمودین انجام دادم بازم مشکل داره
فایل و پیوست کردم
با تشکر
پروژتون رو اصلاح کردم. غلط تایپی داشتید:چشمک:



در ضمن برای تعریف چندیدن استایل تو یک کتابخانه جوابی ندادین

آموزششو همین جا انشالله قرار میدم.




در ضمن برای تعریف چندیدن استایل تو یک کتابخانه جوابی ندادین
یک مشکل دیگه هم بوجود اومده اونم اینه که
در برنامه از کتابخانه کلید برای کاربری و استفاده از توابع اون استفاده شده حالا وقتی کلید جدید رو فراخوانی میکنی به هیچکدوم از اونا دسترسی نداره
با تشکر
میشه واضح تر بگید؟:کف::خجالت::متفکر:

Mori Bone
دوشنبه 11 آبان 1394, 16:38 عصر
ببخشین
یک موضوع دیگه اگه بخوام از DLL ساخته شده در دیگر بنامه ها مثل WinForm استفاده کنم میسر هست
و تعریف اون چه جوری میشه؟؟؟؟؟؟:افسرده:
من اطلاعی ندارم تو نت زیاد در باره ی این موضوع بحث شده

z.neshati
دوشنبه 02 آذر 1394, 11:25 صبح
با سلام و خسته نباشید


میشه یه مثال کوچیک ازش بزنین .

با تشکر

Mori Bone
دوشنبه 02 آذر 1394, 13:17 عصر
با سلام و خسته نباشید


میشه یه مثال کوچیک ازش بزنین .

با تشکر
کله آموزشم مثاله ک:متفکر:
تو تاپیک زیر ی کنترل گذاشتم همراه با سورس ک با همین روشه.
موفق باشید

http://barnamenevis.org/showthread.php?512318-radio-button-%D8%B3%D9%81%D8%A7%D8%B1%D8%B4%DB%8C-%D8%B4%D8%AF%D9%87-(modern-ui)