2011-01-12 18 views
6

Vấn đề của tôi là tôi muốn xử lý một lệnh ở nhiều nơi. Ví dụ tôi có UserControl tùy chỉnh của tôi, nơi một Button được ràng buộc với một số lệnh. Tôi có một lệnh ràng buộc trong điều khiển đó nhưng tôi cũng có một lệnh ràng buộc trong một cửa sổ trong đó sử dụng điều khiển này.RoutedCommands Executed and PreviewExecuted events

Mục đích của tôi là thực hiện một số thao tác bên trong điều khiển trong khi không làm gián đoạn việc xử lý lệnh trong Cửa sổ.

Tôi đã thử nghiệm với các sự kiện đã thực thi và PreviewExecuted nhưng không có may mắn. Sau đó, tôi mô phỏng vấn đề trong một cửa sổ duy nhất (mã được đăng bên dưới).

<Window x:Class="CommandingEvents.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:CommandingEvents="clr-namespace:CommandingEvents" 
    Title="Window1" Height="300" Width="300"> 
<Window.CommandBindings> 
    <CommandBinding 
     Command="{x:Static CommandingEvents:Window1.Connect}" 
     Executed="CommandBindingWindow_Executed" 
     PreviewExecuted="CommandBindingWindow_PreviewExecuted"/> 
</Window.CommandBindings> 
<Grid> 
    <Grid.CommandBindings> 
     <CommandBinding 
     Command="{x:Static CommandingEvents:Window1.Connect}" 
     Executed="CommandBindingGrid_Executed" 
     PreviewExecuted="CommandBindingGrid_PreviewExecuted" /> 
    </Grid.CommandBindings> 
    <Button Command="{x:Static CommandingEvents:Window1.Connect}" 
      CommandTarget="{Binding RelativeSource={RelativeSource Self}}" 
      Content="Test" HorizontalAlignment="Center" VerticalAlignment="Center" /> 
</Grid> 

namespace CommandingEvents 
{ 
    public partial class Window1 
    { 
     public static readonly RoutedUICommand Connect = new 
      RoutedUICommand("Connect", "Connect", typeof(Window1)); 

     public Window1() 
     { 
      InitializeComponent(); 
     } 

     private void CommandBindingWindow_Executed(object sender, ExecutedRoutedEventArgs e) 
     { 
      Console.WriteLine("CommandBindingWindow_Executed"); 
      e.Handled = false; 
     } 

     private void CommandBindingGrid_Executed(object sender, ExecutedRoutedEventArgs e) 
     { 
      Console.WriteLine("CommandBindingGrid_Executed"); 
      e.Handled = false; 
     } 

     private void CommandBindingWindow_PreviewExecuted(object sender, ExecutedRoutedEventArgs e) 
     { 
      Console.WriteLine("CommandBindingWindow_PreviewExecuted"); 
      e.Handled = false; 
     } 

     private void CommandBindingGrid_PreviewExecuted(object sender, ExecutedRoutedEventArgs e) 
     { 
      Console.WriteLine("CommandBindingGrid_PreviewExecuted"); 
      e.Handled = false; 
     } 
    } 
} 

Khi tôi nhấn nút duy nhất "CommandBindingWindow_PreviewExecuted" được in ra. Tại sao vậy? Tôi đã cố gắng đặt e.Handled thành false nhưng nó không tạo ra sự khác biệt. Bất cứ ai có thể giải thích hành vi này?

Trả lời

9

Tôi không có ý tưởng tại sao điều đó xảy ra (và làm thế nào nó không phải là một lỗi) nhưng đây là những gì được viết trong WPF wiki:

Có một đặc thù về CommandBinding mà là cực kỳ thú vị và Quan trọng phải biết.

Các CommandManager sử dụng các sự kiện routed để thông báo cho các đối tượng khác nhau CommandBinding rằng một thực hiện lệnh là gọi (thông qua cử chỉ mặc định, bindings đầu vào, một cách rõ ràng, vv).

Đến nay, điều này khá là đơn giản. Tuy nhiên, điều quan trọng hơn là quan trọng là CommandBinding sẽ đánh dấu sự kiện được định tuyến từ Trình quản lý Tác vụ được xử lý ngay sau khi xử lý (hoặc PreviewExecuted hoặc Executed).

Cuối cùng, ngay cả khi xử lý của bạn có một nguyên mẫu phù hợp với một đại biểu gọi ExecutedRoutedEventHandler, sự kiện đã thi từ CommandBinding không phải là một RoutedEvent nhưng một CLR sự kiện bình thường. Đặt hoặc rời khỏi e.Được chuyển thành sai sẽ thay đổi không có gì.

Do đó, ngay khi đã thực thi hoặc Xem trước Trình xử lý bị xử lý được gọi, RoutedCommand sẽ tạm dừng định tuyến .

+1

Có cách nào để buộc 'RoutedCommand' tiếp tục định tuyến không? –

+0

@Matthew: Well .. Bạn luôn có thể cố gắng nâng cao sự kiện từ phương thức Thực thi. – VitalyB

+0

liên kết tới WPF wiki đã chết. đã di chuyển ở đâu đó? – dtm