2009-08-29 28 views
122

Tôi có một lệnh mà tôi đang thực hiện từ tập tin XAML của tôi bằng cách sử dụng cú pháp tiêu chuẩn sau đây:Đi qua hai tham số lệnh sử dụng một WPF ràng buộc

<Button Content="Zoom" Command="{Binding MyViewModel.ZoomCommand}"/> 

này đã làm việc tốt cho đến khi tôi nhận ra rằng tôi cần HAI mẩu thông tin từ chế độ xem để thực hiện thao tác này hoàn thành cách người dùng mong đợi (chiều rộng và chiều cao của canvas cụ thể).

Nó có vẻ như nó có thể vượt qua một mảng như một đối số lệnh của tôi, nhưng tôi không thấy có trở thành một cách để xác định các ràng buộc để hai thuộc tính canvas của tôi trong CommandParameter:

<Button Content="Zoom" 
     Command="{Binding MyViewModel.ZoomCommand" 
     CommandParameter={Binding ElementName=MyCanvas, Path=Width}"/> 

Làm thế nào để vượt qua cả chiều rộng và chiều cao cho lệnh của tôi? Nó không có vẻ như thế này là có thể bằng cách sử dụng lệnh từ XAML và tôi cần phải dây lên một xử lý nhấp chuột trong codebehind của tôi để có được thông tin này để vượt qua để phương pháp zoom của tôi.

Trả lời

182

Thứ nhất, nếu bạn đang thực hiện MVVM, thông thường bạn sẽ có thông tin này có sẵn cho máy ảo của mình thông qua các thuộc tính riêng biệt được ràng buộc từ chế độ xem. Điều đó giúp bạn tiết kiệm được việc phải chuyển bất kỳ tham số nào đến các lệnh của bạn.

Tuy nhiên, bạn cũng có thể đa bind và sử dụng một bộ chuyển đổi để tạo ra các thông số:

<Button Content="Zoom" Command="{Binding MyViewModel.ZoomCommand"> 
    <Button.CommandParameter> 
     <MultiBinding Converter="{StaticResource YourConverter}"> 
      <Binding Path="Width" ElementName="MyCanvas"/> 
      <Binding Path="Height" ElementName="MyCanvas"/> 
     </MultiBinding> 
    </Button.CommandParameter> 
</Button> 

Trong chuyển đổi của bạn:

public class YourConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, ...) 
    { 
     return values.Clone(); 
    } 

    ... 
} 

Sau đó, trong lệnh thực hiện logic của bạn:

public void OnExecute(object parameter) 
{ 
    var values = (object[])parameter; 
    var width = (double)values[0]; 
    var height = (double)values[1]; 
} 
+1

Cảm ơn Kent - đã được chính xác những gì tôi đang tìm kiếm. Tôi thích cách tiếp cận đầu tiên của bạn tốt hơn để VM biết "trạng thái" của khung nhìn thông qua một ràng buộc mà không cần phải chuyển các tham số chút nào, nhưng tôi vẫn có thể kiểm tra nó. Tôi không chắc rằng nó sẽ làm việc cho tôi ở đây, vì tôi cần quan điểm để làm cho canvas càng lớn càng tốt và chuyển giá trị này cho VM. Nếu tôi ràng buộc nó, tôi sẽ không phải thiết lập chiều rộng trong máy ảo? Trong trường hợp nào, VM bị ràng buộc với khung nhìn? – JasonD

+0

@ Jason: bạn có thể thực hiện theo cách này. Tức là, để chế độ xem đẩy thay đổi trở lại mô hình chế độ xem hoặc có chế độ xem đẩy các thay đổi vào chế độ xem. Một ràng buộc TwoWay sẽ dẫn đến một trong hai tùy chọn có sẵn cho bạn. –

+0

trong chương trình của tôi Tham số phương thức OnExecute là một mảng có giá trị null nhưng, trong trình biến đổi giá trị như mong đợi –

13

Sử dụng Tuple in Converter và trong OnExecute, hãy truyền đối tượng tham số trở lại Tuple.

public class YourConverter : IMultiValueConverter 
{  
    public object Convert(object[] values, ...)  
    { 
     Tuple<string, string> tuple = new Tuple<string, string>(
      (string)values[0], (string)values[1]); 
     return (object)tuple; 
    }  
} 

// ... 

public void OnExecute(object parameter) 
{ 
    var param = (Tuple<string, string>) parameter; 
} 
35

Trong bộ chuyển đổi của giải pháp được lựa chọn, bạn nên thêm values.Clone() nếu không thì các thông số vào cuối lệnh rỗng

public class YourConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, ...) 
    { 
     return values.Clone(); 
    } 

    ... 
} 
+2

Xin chào, bổ sung này với Clone() làm cho nó hoạt động :) Bạn có thể vui lòng giải thích, những gì khác biệt nó. Bởi vì tôi không hiểu tại sao nó cần Clone() để làm việc? Cảm ơn bạn. – adminSoftDK

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