دوستان و علاقمندان به مباحث WPF وقتتون بخیر. با آموزش WPF از وب سایت آموزشی پی وی لرن همراهتون هستیم. با بررسی Routed Events در WPF این بخش از آموزش را نیز ادامه خواهیم داد. در ابتدا انواع Routed Event را بیان نموده و Routed Event سفارشی ایجاد می کنیم. در آخر نیز کدهایی برای کامپایل و اجرا داریم. با ادامه ی آموزش ها ، همراه ما باشید.
یک Routed Events نوعی رویداد است که می تواند در یک درخت عنصر به جای این که فقط شیء رویداد را مطرح کند ، هندلرها را بر روی listener های چندگانه در یک درخت عنصر فراخوانی می کند. در واقع یک رویداد CLR است که توسط نمونه ای از کلاس Routed Event پشتیبانی می شود. با سیستم رویداد WPF ثبت شده است. RoutedEvents سه استراتژی اصلی روت دارد که به شرح زیر است.
یک Direct Event شبیه به وقایع در Windows form ها است که توسط عنصری که در آن رویداد ایجاد می شود مطرح می شود.
بر خلاف یک رویداد استاندارد CLR ، رویدادهای direct routed از مدیریت کلاس پشتیبانی می کنند و می توان از آن ها در Event Setters و Event Triggers در Custom Control خود استفاده کرد.
مثال خوبی از یک Direct Event می تواند رویداد MouseEnter باشد.
یک Bubbling Event با عنصری که در آن رویداد آغاز می شود آغاز می شود. سپس از درخت بصری به بالاترین عنصر درخت بصری می رود. بنابراین ، در WPF ، بالاترین عنصر به احتمال زیاد یک پنجره است.
هندلرهای رویداد روی ریشه درخت عنصر فراخوانی می شوند و سپس این رویداد به پایین درخت بصری به گره های کودکان می پردازد تا این که به عنصری که از آن رویداد سرچشمه گرفته است برسد.
تفاوت بین رویداد bubbling و tunneling در این است که یک رویداد tunneling همیشه با پیش نمایش (preview) آغاز می شود.
در یک برنامه WPF ، رویدادها اغلب به صورت tunneling/bubbling اجرا می شوند. بنابراین ، یک پیش نمایش MouseDown و سپس یک رویداد MouseDown خواهید داشت.
در زیر مثال ساده ای از یک رویداد Routed آورده شده است که در آن یک دکمه و سه بلوک متنی با برخی خصوصیات و وقایع ایجاد شده است.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <Window x:Class = "WPFRoutedEvents.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Title = "MainWindow" Height = "450" Width = "604" ButtonBase.Click = "Window_Click" > <Grid> <StackPanel Margin = "20" ButtonBase.Click = "StackPanel_Click"> <StackPanel Margin = "10"> <TextBlock Name = "txt1" FontSize = "18" Margin = "5" Text = "This is a TextBlock 1" /> <TextBlock Name = "txt2" FontSize = "18" Margin = "5" Text = "This is a TextBlock 2" /> <TextBlock Name = "txt3" FontSize = "18" Margin = "5" Text = "This is a TextBlock 3" /> </StackPanel> <Button Margin = "10" Content = "Click me" Click = "Button_Click" Width = "80"/> </StackPanel> </Grid> </Window> |
در این جا کد #C برای اجرای رویدادهای Click برای دکمه ، StackPanel و Window آورده شده است.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | using System.Windows; namespace WPFRoutedEvents { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { txt1.Text = "Button is Clicked"; } private void StackPanel_Click(object sender, RoutedEventArgs e) { txt2.Text = "Click event is bubbled to Stack Panel"; } private void Window_Click(object sender, RoutedEventArgs e) { txt3.Text = "Click event is bubbled to Window"; } } } |
وقتی کد بالا را کامپایل و اجرا می کنید ، پنجره زیر را ایجاد می کند.
هنگامی که بر روی دکمه کلیک می کنید ، مطابق شکل زیر بلوک های متن به روز می شوند.
اگر می خواهید routed event را در هر سطح خاصی متوقف کنید ، باید e.Handled = true را تنظیم کنید.
بیایید رویداد StackPanel_Click را مطابق شکل زیر تغییر دهیم.
1 2 3 4 | private void StackPanel_Click(object sender, RoutedEventArgs e) { txt2.Text = "Click event is bubbled to Stack Panel"; e.Handled = true; } |
با کلیک بر روی دکمه ، مشاهده می کنید که رویداد کلیک به پنجره هدایت نمی شود و در stackpanel متوقف می شود و بلوک متن ۳ به روز نمی شود.
در چارچوب NET. ، رویداد Routed سفارشی نیز می تواند تعریف شود. برای تعریف یک routed event سفارشی در #C باید مراحل زیر را دنبال کنید.
بیایید مثالی بزنیم تا درباره routed event های سفارشی مسیریابی بیش تر بدانیم. مراحل زیر را دنبال کنید.
کادر گفتگوی زیر باز خواهد شد ، اکنون (Custom Control (WPF را انتخاب کرده و نام آن را MyCustomControl بگذارید.
بر روی دکمه Add کلیک کنید و خواهید دید که دو فایل جدید (Themes/Generic.xaml و MyCustomControl.cs) در solution شما اضافه خواهند شد.
کد XAML زیر سبک کنترل سفارشی را در فایل Generic.xaml تعیین می کند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <ResourceDictionary xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "clr-namespace:WPFCustomRoutedEvent"> <Style TargetType = "{x:Type local:MyCustomControl}"> <Setter Property = "Margin" Value = "50"/> <Setter Property = "Template"> <Setter.Value> <ControlTemplate TargetType = "{x:Type local:MyCustomControl}"> <Border Background = "{TemplateBinding Background}" BorderBrush = "{TemplateBinding BorderBrush}" BorderThickness = "{TemplateBinding BorderThickness}"> <Button x:Name = "PART_Button" Content = "Click Me" /> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary> |
در زیر کد #C برای کلاس MyCustomControl آورده شده است که از کلاس Control به دست می آید که در آن یک routed event Click برای کنترل سفارشی ایجاد می شود.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | using System.Windows; using System.Windows.Controls; namespace WPFCustomRoutedEvent { public class MyCustomControl : Control { static MyCustomControl() { DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl))); } public override void OnApplyTemplate() { base.OnApplyTemplate(); //demo purpose only, check for previous instances and remove the handler first var button = GetTemplateChild("PART_Button") as Button; if (button ! = null) button.Click + = Button_Click; } void Button_Click(object sender, RoutedEventArgs e) { RaiseClickEvent(); } public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyCustomControl)); public event RoutedEventHandler Click { add { AddHandler(ClickEvent, value); } remove { RemoveHandler(ClickEvent, value); } } protected virtual void RaiseClickEvent() { RoutedEventArgs args = new RoutedEventArgs(MyCustomControl.ClickEvent); RaiseEvent(args); } } } |
در این جا اجرای routed event سفارشی در #C است که وقتی کاربر روی آن کلیک کند ، یک جعبه پیام نمایش داده می شود.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | using System.Windows; namespace WPFCustomRoutedEvent { // <summary> // Interaction logic for MainWindow.xaml // </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void MyCustomControl_Click(object sender, RoutedEventArgs e) { MessageBox.Show("It is the custom routed event of your custom control"); } } } |
در این جا پیاده سازی در MainWindow.xaml برای اضافه کردن کنترل سفارشی با یک routed event Click وجود دارد.
1 2 3 4 5 6 7 8 9 10 11 | <Window x:Class = "WPFCustomRoutedEvent.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "clr-namespace:WPFCustomRoutedEvent" Title = "MainWindow" Height = "350" Width = "604"> <Grid> <local:MyCustomControl Click = "MyCustomControl_Click" /> </Grid> </Window> |
وقتی کد فوق کامپایل و اجرا می شود، پنجره ی زیر زا تولید می کند که شامل یک کنترل سفارشی است.
هنگامی که شما بر روی کنترل سفارشی کلیک کنید ، پیام زیر را تولید می کند.
دوستان عزیز متشکریم از این که تا این بخش از آموزش همراه بودید. در این بخش از آموزش WPF ، انواع Routed Event را نام بردیم و Routed Event های سفارشی را نیز ایجاد نمودیم. در ادامه برای درک بهتر ، مثال هایی نیز زده شد. امیدوارم این بخش از آموزش نیز مورد توجه قرار گرفته باشد. در بخش بعد به بررسی کنترل ها (Control ها) خواهیم پرداخت. با ادامه ی آموزش و وب سایت آموزشی پی وی لرن همراه باشید.