2009-03-19 13 views
20

Trong bài viết MSDN Understanding Routed Events and Commands In WPF, nó khẳng địnhTại sao không bấm nút sự kiện "bong bóng lên cây trực quan" để StackPanel như tiểu bang bài viết MSDN?

một sự kiện sẽ bong bóng (tuyên truyền) lên cây thị giác từ các yếu tố nguồn cho đến khi một trong hai nó đã được xử lý hoặc nó đạt đến phần tử gốc.

Tuy nhiên, trong ví dụ này, khi bạn nhấp vào nút, nó không "bong bóng lên cây thị giác" để xử lý bởi phụ huynh StackPanel kiện, ví dụ: cách nhấp vào nút cháy không có sự kiện.

Tại sao không? Vậy ý của chúng là gì bằng cách "sủi bọt" nếu không?

XAML:

<Window x:Class="TestClickEvents456.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <StackPanel x:Name="TheStackPanel" 
       Background="Yellow" 
       MouseDown="TheStackPanel_MouseDown"> 
     <Button x:Name="TheButton" 
       Margin="10" 
       Content="Click This"/> 
     <TextBlock x:Name="TheMessage" 
        Text="Click the button or the yellow area"/> 
    </StackPanel> 
</Window> 

code-behind:

using System.Windows; 
using System.Windows.Input; 

namespace TestClickEvents456 
{ 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 
     } 

     private void TheStackPanel_MouseDown(object sender, MouseButtonEventArgs e) 
     { 
      TheMessage.Text = "StackPanel was clicked."; 
     } 

    } 
} 

Trả lời

22

Sự kiện bong bóng lên, cho đến khi nó được xử lý ...

Kể từ khi nút làm điều gì đó với nhấp chuột của bạn, nó hấp thụ sự kiện chuột của bạn và biến nó thành một ClickEvent.

Nếu bạn sử dụng PreviewMouseDown, bạn thấy rằng StackPanel đầu tiên nhận được sự kiện này trước khi vào nút thực hiện .. Xem trước các sự kiện sử dụng phương pháp hầm xuống ..

+1

nút này hoạt động với cú click chuột của tôi là gì? Tôi không có thuộc tính nhấp chuột nào trong phần tử, tôi không xử lý sự kiện nhấp chuột trong mã phía sau, vì vậy làm cách nào chúng tôi có thể nói nút đang làm điều gì đó với các lần nhấp chuột? –

+0

PreviewMouseDown hoạt động, cảm ơn. –

+2

Đúng, nhưng việc thực hiện mặc định của nút là hấp thụ sự kiện chuột của bạn để biến nó thành sự kiện nhấp ... ngay cả khi bạn không làm gì với lần nhấp ... – Arcturus

1

Nó được bởi vì tất cả các thông điệp đang được bắt xử lý bởi Nút và tin nhắn dừng lại tin nhắn dừng lại sủi bọt ở đó. Câu trả lời là đúng trong văn bản của câu hỏi của bạn:

Một sự kiện sẽ bong bóng (tuyên truyền) lên cây thị giác từ các yếu tố nguồn cho đến khi một trong hai nó đã được xử lý hoặc nó đạt đến phần tử gốc.

EDIT:

Edward Tanguay (OP) nhận xét về câu trả lời này và tôi đang sao chép bình luận của mình ở đây vì nó là rất có liên quan:

"Tôi không thấy rằng nút LÀ xử lý sự kiện, tức là tôi không có trình xử lý nhấp chuột nào trên nút, tôi có trình xử lý nhấp chuột (MouseDown) trên StackPanel và do đó tôi nghĩ rằng nó sẽ làm bong bóng nút PAST vì nút đó không xử lý và xử lý stackpanel, đúng không? "

Bạn nói đúng. Nút không xử lý sự kiện MouseDown vì không có trình xử lý nào được chỉ định cho nó tại điều khiển đó.

Nhưng, sau đó, MouseDown đặc biệt theo một cách nào đó. Ít nhất trong Windows Forms nó được sử dụng để khởi tạo các hành động như vẽ và kéo như vậy, khi điều khiển nhận được sự kiện, nó tiến hành bẫy tất cả các thông báo chuột tiếp theo ngay cả khi bạn chưa xác định trình xử lý cho nó.Cái bẫy này được thực hiện khi bộ điều khiển Capture bất động sản thành True và điều này ngăn chặn hiệu quả các sự kiện tiếp theo. Capture property được thiết lập trở lại False bởi Windows Forms khi nó nhận được một sự kiện MouseUp.

Tôi lặp lại, đây là cách nó hoạt động trong Windows Forms, bạn có thể muốn kiểm tra lại điều này nhưng, IMHO không có lý do tại sao điều này nên khác nhau đối với WPF.

Để tham khảo: Se phần "Xử lý biểu mẫu Windows" tại http://blogs.msdn.com/jfoscoding/archive/2005/07/28/444647.aspx (cuộn nhẹ xuống từ giữa trang).

Lưu ý: Xem nhận xét của tôi về câu trả lời của Arcturu để tham khảo về các sự kiện bong bóng và đường hầm nâng cao trình tự.

+0

Tôi không thấy rằng nút IS xử lý sự kiện, tức làTôi không có trình xử lý nhấp chuột nào trên nút, tôi có trình xử lý nhấp chuột (MouseDown) trên StackPanel và do đó tôi sẽ nghĩ rằng nó sẽ bong bóng PAST nút vì nút này không xử lý và được xử lý bởi stackpanel, đúng? –

+0

Bạn nói đúng. Tôi đã chỉnh sửa câu trả lời của mình. – vmarquez

7

Bên cạnh đó, nếu bạn muốn stackpanel nhận sự kiện này, thay đổi XAML stackpanel tới:

<StackPanel x:Name="TheStackPanel" 
      Background="Yellow" 
      Button.Click="TheStackPanel_MouseDown" /> 

và chữ ký sự kiện:

private void TheStackPanel_MouseDown(object sender, RoutedEventArgs e) 

Trong trường hợp này, stackpanel sẽ nhận sự kiện nhấp của nút. Tuy nhiên, việc nhấp vào bản thân stackpanel sẽ không kích hoạt bất kỳ sự kiện nào vì nó lắng nghe cụ thể đến một lần nhấp nút.

+0

hmm, tôi đã nhìn thấy các Button.Click trong bài viết là tốt nhưng StackPanel của tôi không có thuộc tính đó (?), Thuộc tính tương tự duy nhất tôi nhận được trong intellisense là "ButtonBase.Click" mang lại cho tôi "Không quá tải cho ' TheStackPanel_MouseDown 'khớp với đại biểu' System.Windows.RoutedEventHandler '", tại sao vậy? –

+0

Hmmm, nó hoạt động cho tôi với cả hai ButtonBase.Click và Button.Click trong XAML (Tôi tin Button.Click chỉ không hiển thị trong intellisense - nhưng nó sẽ làm việc) - và với chữ ký sự kiện được chỉ định. Bạn đã thay đổi MouseButtonEventArgs thành RoutedEventArgs chưa? – Razzie

8

Như những người khác đã nói, đó là vì sự kiện MouseDown được xử lý bởi Button trước khi nó có thể được thêm bọt. Bạn có thể thấy điều này trong suy nghi, trong ButtonBase.OnMouseLeftButtonDown:

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) 
{ 
    if (this.ClickMode != ClickMode.Hover) 
    { 
     e.Handled = true; 
     // SNIP... 
    } 
    base.OnMouseLeftButtonDown(e); 
} 

Một giải pháp là để lắng nghe một sự kiện MouseDown, và chỉ ra rằng bạn không quan tâm nếu sự kiện được xử lý. Bạn có thể làm điều này với phương pháp AddHandler. Nó có quá tải boolean cho phép bạn nghe các sự kiện đã được xử lý.

Nếu bạn làm điều này ở đâu đó thay vì thiết lập các handler MouseDown trong XAML:

TheStackPanel.AddHandler(MouseDownEvent, new MouseButtonEventHandler(TheStackPanel_MouseDown), true); 

Bạn sẽ nhận được tất cả các sự kiện trên MouseDownTheStackPanel, bất kể họ đã được xử lý.

+0

"MouseDownEvent" là gì? RoutedEvent là một lớp được niêm phong, vì vậy một số đối tượng phải mang các cá thể của chúng? – flq

+0

Ah, tìm thấy một cái gì đó. 'Mouse.AddXXX (DependencyObject, EventHandler);' – flq

2

nút kiện Suppress các mousedown và mouseup vì nút sự kiện là sự kiện cấp cao và có chút mã mà cung cấp cho cán cờ áp đúng nguyên nhân này Bị chặn cho mousdown để giải quyết vấn đề này bạn có thể thêm mã này trong constructor của cửa sổ

TheButton.AddHandler(
    UIElement.MouseDownEvent, 
    new MouseButtonEventHandler(TheStackPanel_MouseDown), 
    true); 
Các vấn đề liên quan