WPF – Routed Event

Routed Event là một kiểu event mới với cách thức hoạt động hiệu quả hơn so với .NET event thông thường. Chúng có thể được lắng nghe bởi nhiều thành phần và thay đổi hướng lan truyền sự kiện lên hoặc xuống trên element tree.

Event Routing

Routed Event chia ra ba cách lan truyền sự kiện là:

  • Direct: giống như .NET event,  chỉ có một thành phần duy nhất kích hoạt và bắt event.
  • Bubbling: event sẽ lan truyền từ thành phần kích hoạt lên thành phần gốc của element tree. Đa số các routed event đều được lan truyền theo kiểu này.

 

  • Tunneling: ngược với bubbling, event được lan truyền từ thành phần gốc của element tree xuống thành phần kích hoạt. Theo tiêu chuẩn đặt tên thì các event kiểu này có tên theo dạng PreviewXYZ (ví dụ PreviewKeyUp, PreviewMouseDown,…)

Giả sử ta có đoạn XAML sau gồm hai thành phần là DockPanel và Button. Cả hai đều dùng phương thức Element Tree để xử lý sự kiện Button.Click:

<DockPanel Button.Click="Element_Click">
        <Button Click="Element_Click">Click Me</Button>
</DockPanel>

Và phương thức quản lý sự kiện trong code-behind có mục đích hiển thị kiểu của đối tượng bắt sự hiện (sender) và đối tượng kích hoạt sự kiện (e.Source):

private void Element_Click(object sender, RoutedEventArgs e)
{
       MessageBox.Show("Sender: "+ sender.GetType().Name);
}

Kết quả khi bạn click vào button thì sẽ lần lượt hiện lên hai Message với nội dung sau:

Sender: Button
Sender: DockPanel

Như vậy cả hai đối tượng Button và DockPanel đều nhận được sự kiện Click và lan truyền theo kiểu Bubbling (Button -> DockPanel). Sự kiện Button.Click mà ta viết trong thẻ DockPanel được gọi là Attached event, tương tự như Attached property trong WPF.

Thay vì thử với event Click, bạn có thể thay bằng event PreviewMouseDown, thứ tự xử lý event sẽ ngược lại với ví dụ trên:

Sender: DockPanel
Sender: Button

bởi vì PreviewMouseDown là một event theo kiểu Tunneling.

Nếu bạn muốn ngừng việc lan truyền event này, chỉ cần đặt property RoutedEventArgs.Handled là true:

private void Button_Click(object sender, RoutedEventArgs e)
{
    // do something
    e.Handled = true;
}

Thêm các Event Handler

Theo cách thông thường ta sẽ viết theo dạng một attribute trong tài liệu XAML và cùng với đó là tạo một phương thức để xử lý event:

<Button Click=”Button_Click”>Button 1</Button>

Phương thức xử lý event phải khớp với delegate event handler mà event được khai báo, với event Click, event handler tương ứng là RoutedEventHandler:

public delegate void RoutedEventHandler(
        Object sender,
        RoutedEventArgs e
)

Thay vì viết trong XAML, ta có thể làm tương tự trong code-behind như .NET event thông thường:

button1.Click += new RoutedEventHandler(Button_Click);
button1.Click -= new RoutedEventHandler(Button_Click);

Hoặc sử dụng hai phương thức UIElement.AddHandler() và UIElement.RemoveHandler()

button1.AddHandler(Button.ClickEvent, new RoutedEventHandler(Button_Click));

button1.RemoveHandler(Button.ClickEvent,  new RoutedEventHandler(Button_Click));

Kích hoạt Event

Để làm việc này ta dùng phương thức UIElement.RaiseEvent() với tham số là một đối tượng RoutedEventArgs.

RoutedEventArgs e = new RoutedEventArgs(Button.ClickEvent, button1);
RaiseEvent(e);

Tạo Routed Event

Việc tạo routed event tương tự như tạo các Dependency property, ở đây ta dùng phương thức EventManager.RegiserRoutedEvent() để đăng kí và tạo một thể hiện của routed event.  Tham số thứ hai của phương thức này là một kiểu từ enum RoutingStrategy bao gồm ba giá trị tương ứng với các event routing là: Direct, Bubble và Tunnel.

public static readonly RoutedEvent DoSomethingEvent = EventManager.RegisterRoutedEvent(
      "DoSomething", RoutingStrategy.Bubble,
      typeof(RoutedEventHandler), typeof(MyButton));

// .NET event wrapper.
public event RoutedEventHandler DoSomething
{
    add
    {
        base.AddHandler(DoSomethingEvent, value);
    }
    remove
    {
        base.RemoveHandler(DoSomethingEvent, value);
    }
}

https://yinyangit.wordpress.com

Advertisements

Trả lời

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s