2010-02-18 34 views
9

Tôi có một UserControl cho biết thêm một CommandBinding để nó CommandBindings bộ sưu tập để xử lý một lệnh cụ thể. Sau đó, tôi sử dụng điều khiển này trong một cửa sổ và muốn thêm một ràng buộc khác vào cùng điều khiển đó để thêm hành vi bổ sung. Vấn đề là, khi tôi làm điều này, có vẻ như khi tôi thêm một CommandBinding khác vào bộ sưu tập CommandBindings của một điều khiển, nó sẽ thay thế bất kỳ ràng buộc nào đã được tạo ra cho cùng một Lệnh. Vì vậy, những gì nó có vẻ như là một điều khiển chỉ có thể có một CommandBinding duy nhất cho mỗi kiểm soát, là điều này đúng?Tôi có thể có nhiều CommandBindings cho cùng một Lệnh trên cùng một điều khiển không?

Vui lòng xem ví dụ mã bên dưới cố gắng đặt hai CommandBindings cho cùng một lệnh Lưu.

<Window x:Class="MultipleCommandBindings.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"> 
<Window.CommandBindings> 
    <CommandBinding Command="Save" 
        Executed="CommandBinding_Executed" /> 
    <CommandBinding Command="Save" 
        Executed="CommandBinding_Executed" /> 
</Window.CommandBindings> 
<Grid> 
    <Button Height="23" 
      HorizontalAlignment="Right" 
      Margin="0,0,25,88" 
      Name="button1" 
      VerticalAlignment="Bottom" 
      Width="75" 
      Command="Save">Button</Button> 
</Grid> 

Nguyên tôi đã mong đợi hoặc là một thời gian biên dịch hoặc ngoại lệ thời gian chạy khi viết mã này, nhưng rất ngạc nhiên rằng nó đã không phàn nàn. Tiếp theo mặc dù tôi đã thất vọng vì xử lý CommandBinding_Executed của tôi chỉ được gọi một lần thay vì hai lần như tôi đã hy vọng.

Cập nhật: Sau một chút thử nghiệm dường như CommandBinding thứ hai của tôi không được ghi đè lên người đầu tiên của tôi, nhưng thay vào đó nó xuất hiện rằng mặc dù tôi không đặt cài Cầm là true trong xử lý sự kiện của tôi rằng lệnh đầu tiên ràng buộc nuốt lệnh. Tôi khá chắc chắn vào thời điểm này rằng giải pháp cho vấn đề của tôi là để hiểu tại sao lệnh được định tuyến không được truyền qua trình xử lý đầu tiên ngay cả khi Handled không được đặt thành true.

Cập nhật: Tôi đã tìm thấy this great little tidbit thông tin xác nhận một số hành vi lạ đằng sau Lệnh định tuyến trong WPF.

Cập nhật: Một suy nghĩ về làm thế nào để làm việc xung quanh thực tế là nó xuất hiện mà chỉ có thể có một CommandBinding hiệu quả duy nhất cho mỗi lệnh là nó xuất hiện rằng lớp CommandBinding mặc định thấy nhiều thực thi và CanExecute như các sự kiện trong đó tất nhiên giống như tất cả các sự kiện có thể có nhiều trình xử lý. Ý tưởng sau đó là có một số cách khác hơn so với phương thức CommandBindings.Add chuẩn để thêm các trình xử lý bổ sung vào một lệnh. Có lẽ điều này có thể được thực hiện thông qua một phương thức mở rộng trên lớp Control và kết hợp với một lớp CompositeCommandBinding tùy chỉnh cho phép chúng ta tổng hợp nhiều ràng buộc trong một ràng buộc chính.

+0

Giải pháp duy nhất tôi có thể nghĩ là đăng ký sự kiện Click của Button và sau đó truyền DataContext của View như ViewModel của nó và sử dụng var đó để thực hiện 2 lệnh thủ công. –

Trả lời

1

Tôi không biết câu trả lời cho câu hỏi của bạn, nhưng sử dụng âm thanh phản xạ hợp lý với tôi.

Tôi tự hỏi tại sao bạn lại làm điều này? Có lẽ nó có ý nghĩa hơn để sử dụng mô hình Composite để tổng hợp các hành vi, thay vì sau đó cố gắng kết hợp các ràng buộc lệnh?

+1

+1 cho khái niệm rằng bạn chỉ nên có 1 liên kết trong khung nhìn và cho phép nhiều hành vi được gọi tiếp tục xuống ngăn xếp. –

+0

Vâng, trong trường hợp của tôi, tôi có một điều khiển người dùng có thể là nguồn của nhiều loại lệnh khác nhau được truyền bá đến từ một điều khiển nội bộ. Trong điều khiển người dùng, tôi muốn biết khi nào các lệnh này được phát hành để tôi có thể có một ViewModel khởi tạo một số quy trình khác mà kết quả cuối cùng sẽ được hiển thị thông qua UserControl (View) của tôi. Tôi có thể liên kết với tài sản mà tôi đang phơi bày và thấy khi nào nó thay đổi để biết khi nào nó sẵn sàng sử dụng nhưng tôi nhìn thông tin về loại lệnh thực sự đã bắt đầu toàn bộ quá trình. – jpierson

3

Cho đến nay tôi chỉ có thể đưa ra giải pháp cho vấn đề này là xử lý lệnh ở hai cấp độ khác nhau trong cây logic. Trong ví dụ bên dưới, tôi xử lý lệnh Lưu trong lưới của tôi và sau đó cũng lại trong phần tử Window.

<Window x:Class="MultipleCommandBindings.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"> 
<Window.CommandBindings> 
    <CommandBinding Command="Save" 
        Executed="CommandBinding_Executed2"/> 
</Window.CommandBindings> 
<Grid> 
    <Grid.CommandBindings> 
     <CommandBinding Command="Save" 
         Executed="CommandBinding_Executed1" /> 
    </Grid.CommandBindings> 

    <Button Height="23" 
      HorizontalAlignment="Right" 
      Margin="0,0,25,88" 
      Name="button1" 
      VerticalAlignment="Bottom" 
      Width="75" 
      Command="Save">Button</Button> 
</Grid> 

Để có được điều này để làm việc mã của tôi đằng sau cần phải cũng bằng tay tuyên truyền việc thực hiện lệnh để cấp độ tiếp theo lên.

private void CommandBinding_Executed1(object sender, ExecutedRoutedEventArgs e) 
    { 
     System.Diagnostics.Debug.WriteLine("Executed 1!"); 
     var command = e.Command as RoutedUICommand; 
     command.Execute(e.Parameter, this); 
    } 

    private void CommandBinding_Executed2(object sender, ExecutedRoutedEventArgs e) 
    { 
     System.Diagnostics.Debug.WriteLine("Executed 2!"); 
    } 

Nếu ai có bất kỳ ý tưởng tốt hơn về cách tôi có thể giám sát một lệnh vẫn để cho nó lan truyền một cách tự nhiên lên cây tôi rất thích nhìn thấy nó nếu không tôi chỉ có thể dùng đến cách giải quyết này.

Các vấn đề liên quan