WPF - เหตุการณ์ที่กำหนดเส้นทาง
ก routed eventเป็นเหตุการณ์ประเภทหนึ่งที่สามารถเรียกใช้ตัวจัดการกับผู้ฟังหลายคนในโครงสร้างองค์ประกอบแทนที่จะเป็นเพียงวัตถุที่ยกเหตุการณ์ โดยพื้นฐานแล้วเป็นเหตุการณ์ CLR ที่สนับสนุนโดยอินสแตนซ์ของคลาส Routed Event มีการลงทะเบียนกับระบบเหตุการณ์ WPF RoutedEvents มีกลยุทธ์การกำหนดเส้นทางหลักสามแบบซึ่งมีดังต่อไปนี้ -
- เหตุการณ์โดยตรง
- เหตุการณ์ฟองสบู่
- เหตุการณ์อุโมงค์
เหตุการณ์โดยตรง
เหตุการณ์โดยตรงคล้ายกับเหตุการณ์ในรูปแบบของ Windows ซึ่งเกิดขึ้นโดยองค์ประกอบที่เหตุการณ์นั้นเกิดขึ้น
ไม่เหมือนกับเหตุการณ์ CLR มาตรฐานเหตุการณ์ที่กำหนดเส้นทางโดยตรงรองรับการจัดการคลาสและสามารถใช้ในตัวตั้งค่าเหตุการณ์และทริกเกอร์เหตุการณ์ภายในสไตล์การควบคุมแบบกำหนดเองของคุณ
ตัวอย่างที่ดีของเหตุการณ์โดยตรงคือเหตุการณ์ MouseEnter
เหตุการณ์ฟองสบู่
เหตุการณ์ที่เดือดปุด ๆ เริ่มต้นด้วยองค์ประกอบที่เป็นจุดเริ่มต้นของเหตุการณ์ จากนั้นจะเดินทางขึ้นต้นไม้ภาพไปยังองค์ประกอบที่อยู่บนสุดในแผนผังภาพ ดังนั้นใน WPF องค์ประกอบที่อยู่บนสุดน่าจะเป็นหน้าต่าง
เหตุการณ์อุโมงค์
ตัวจัดการเหตุการณ์บนรากขององค์ประกอบจะถูกเรียกใช้จากนั้นเหตุการณ์จะเดินทางไปตามแผนผังภาพไปยังโหนดลูกทั้งหมดจนกว่าจะถึงองค์ประกอบที่เหตุการณ์นั้นเกิดขึ้น
ความแตกต่างระหว่างเหตุการณ์ที่มีฟองและการสร้างอุโมงค์คือเหตุการณ์การสร้างอุโมงค์จะเริ่มต้นด้วยการแสดงตัวอย่างเสมอ
ในแอปพลิเคชัน WPF มักใช้เหตุการณ์เป็นคู่ทันเนล / บับเบิ้ล ดังนั้นคุณจะมีตัวอย่าง MouseDown และเหตุการณ์ MouseDown
ด้านล่างนี้เป็นตัวอย่างง่ายๆของเหตุการณ์ที่กำหนดเส้นทางซึ่งปุ่มและสามบล็อกข้อความถูกสร้างขึ้นด้วยคุณสมบัติและเหตุการณ์บางอย่าง
<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 # สำหรับการใช้งานเหตุการณ์คลิกสำหรับปุ่ม StackPanel และ Window
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";
}
}
}
เมื่อคุณคอมไพล์และรันโค้ดด้านบนจะมีหน้าต่างดังต่อไปนี้ -
เมื่อคุณคลิกที่ปุ่มบล็อกข้อความจะได้รับการอัปเดตดังที่แสดงด้านล่าง
หากคุณต้องการหยุดเหตุการณ์ที่กำหนดเส้นทางในระดับใดระดับหนึ่งคุณจะต้องตั้งค่า e.Handled = true;
มาเปลี่ยนไฟล์ StackPanel_Click เหตุการณ์ดังภาพด้านล่าง -
private void StackPanel_Click(object sender, RoutedEventArgs e) {
txt2.Text = "Click event is bubbled to Stack Panel";
e.Handled = true;
}
เมื่อคุณคลิกที่ปุ่มคุณจะสังเกตได้ว่าเหตุการณ์การคลิกจะไม่ถูกส่งไปยังหน้าต่างและจะหยุดที่สแต็กพาเนลและบล็อกข้อความrd 3 จะไม่ได้รับการอัปเดต
กำหนดเส้นทางเหตุการณ์ที่กำหนดเอง
ใน. NET framework ยังสามารถกำหนดเหตุการณ์ที่กำหนดเส้นทางเองได้ คุณต้องทำตามขั้นตอนที่ระบุด้านล่างเพื่อกำหนดเหตุการณ์ที่กำหนดเส้นทางเองใน C #
ประกาศและลงทะเบียนเหตุการณ์ที่กำหนดเส้นทางของคุณด้วยระบบเรียก RegisterRoutedEvent
ระบุกลยุทธ์การกำหนดเส้นทางเช่น Bubble, Tunnel หรือ Direct
ระบุตัวจัดการเหตุการณ์
ลองดูตัวอย่างเพื่อทำความเข้าใจเพิ่มเติมเกี่ยวกับเหตุการณ์ที่กำหนดเส้นทางเอง ทำตามขั้นตอนด้านล่าง -
สร้างโปรเจ็กต์ WPF ใหม่ด้วย WPFCustomRoutedEvent
คลิกขวาที่โซลูชันของคุณแล้วเลือกเพิ่ม> รายการใหม่ ...
กล่องโต้ตอบต่อไปนี้จะเปิดขึ้นตอนนี้เลือก Custom Control (WPF) และตั้งชื่อ MyCustomControl.
คลิก Add และคุณจะเห็นว่าไฟล์ใหม่สองไฟล์ (Themes / Generic.xaml และ MyCustomControl.cs) จะถูกเพิ่มเข้าไปในโซลูชันของคุณ
โค้ด XAML ต่อไปนี้ตั้งค่าสไตล์สำหรับคอนโทรลแบบกำหนดเองในไฟล์ Generic.xaml
<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 class ซึ่งสืบทอดมาจากไฟล์ Control class ซึ่งเหตุการณ์ที่กำหนดเส้นทางเอง Click ถูกสร้างขึ้นสำหรับคอนโทรลแบบกำหนดเอง
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);
}
}
}
นี่คือการใช้งานเหตุการณ์ที่กำหนดเส้นทางเองใน C # ซึ่งจะแสดงกล่องข้อความเมื่อผู้ใช้คลิก
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 เพื่อเพิ่มการควบคุมแบบกำหนดเองด้วยเหตุการณ์ที่กำหนดเส้นทางคลิก
<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>
เมื่อโค้ดด้านบนถูกคอมไพล์และเรียกใช้โค้ดจะสร้างหน้าต่างต่อไปนี้ซึ่งมีคอนโทรลแบบกำหนดเอง
เมื่อคุณคลิกที่คอนโทรลแบบกำหนดเองมันจะสร้างข้อความต่อไปนี้