2010-08-14 45 views
7

Tôi đang sử dụng MVVM và các đối tượng ICommand tùy chỉnh được cung cấp bởi lớp ViewModel. Một đối tượng ViewModel cùng một lúc có thể được đính kèm thông qua thuộc tính DataContext tới nhiều đối tượng View (cửa sổ, trang, v.v.). Trong ICommand.CanExecute() tôi muốn kiểm tra sự vắng mặt của các lỗi xác nhận đối với một số điều khiển trong View (được gắn với các đạo cụ ViewModel, đáng kể đối với một lệnh VM cụ thể). Một ViewModel có thể cung cấp nhiều lệnh, mỗi lệnh có bộ điều khiển riêng để xác minh xác thực lỗi. Vì vậy, giả XAML là:WPF: Làm thế nào để vượt qua toàn bộ kiểm soát như CommandParameter thông qua XAML?

<Button.CommandParameter> 
    <x:Array Type="sys_win:DependencyObject"> 
     <sys_win:DependencyObject> 
      <reference_to_textbox_or_other_control/> 
     </sys_win:DependencyObject> 
     <sys_win:DependencyObject> 
      <reference_to_textbox_or_other_control/> 
     </sys_win:DependencyObject> 
    </x:Array> 
</Button.CommandParameter> 

Vấn đề thứ hai là các lệnh đặc biệt có thể được gọi bằng cách điều khiển, mà chính nó là một phần của DataTemplate cho mặt hàng bộ sưu tập (trong trường hợp của tôi - một phần của ListBoxItem mẫu dữ liệu) . Mục danh sách templated của tôi có hai hộp văn bản (liên kết với hai đạo cụ của ViewModel tương ứng) và nút, gọi lệnh ViewModel. Vì vậy, trong lệnh CanExecute() tôi cần phải kiểm tra lỗi xác nhận cho một số điều khiển cửa sổ & hai hộp văn bản, thuộc về danh sách này, không phải các mục khác. Đoạn code dưới đây hoạt động tốt nếu tôi muốn vượt qua tài sản ListBoxItem.IsSelected như CommandParameter:

<Button DataContext="{Binding}" 
     Command="{Binding Path=SwitchCommand}" 
     CommandParameter="{Binding Path=IsSelected, RelativeSource={ 
            RelativeSource 
            Mode=FindAncestor, 
            AncestorType={x:Type ListBoxItem}}}"/> 

Nhưng làm thế nào tôi có thể vượt qua toàn bộ (DependencyObject) ListBoxItem như CommandParameter? Và làm thế nào ListBoxItem này, thông qua {Binding RelativeSource} có thể được trộn lẫn với các điều khiển cửa sổ hiện tại trong ví dụ mã đầu tiên?


Tôi rất tiếc, nhưng làm cách nào để thêm tham chiếu vào điều khiển trong xaml?

<Button.CommandParameter> 
    <x:Array Type="sys_win:DependencyObject"> 
     <sys_win:DependencyObject> 
      <reference_to_textbox_or_other_control/> 
     </sys_win:DependencyObject> 
     <sys_win:DependencyObject> 
      <reference_to_textbox_or_other_control/> 
     </sys_win:DependencyObject> 
    </x:Array> 
</Button.CommandParameter> 
+0

StackOverflow không phải là diễn đàn; nếu bạn cần thêm các chi tiết khác, vui lòng [chỉnh sửa câu hỏi của bạn] (http://stackoverflow.com/posts/3482343/edit). Câu trả lời được cho là câu trả lời, không phải là thông tin bổ sung về câu hỏi. – Will

Trả lời

23

Chỉ cần sử dụng một ràng buộc với không Path:

<Button DataContext="{Binding}" 
     Command="{Binding Path=SwitchCommand}" 
     CommandParameter="{Binding RelativeSource= 
            {RelativeSource 
            Mode=FindAncestor, 
            AncestorType={x:Type ListBoxItem}}}"/> 
+0

Thomas Levesque, cảm ơn bạn. Làm việc của nó, :) –

1

Tôi không chắc chắn nếu tôi đọc ví dụ của bạn một cách chính xác, nhưng có vẻ như vi phạm một chút nguyên tắc MVVM. (Xin lỗi nếu tôi đọc không chính xác).

Ý tưởng đằng sau MVVM là tách mô hình chế độ xem khỏi mọi phụ thuộc trên thực thể XAML/Chế độ xem. Bạn đang phá vỡ đó bằng cách có CommandParameter phụ thuộc vào usercontrol. Những gì tôi sẽ làm là tạo tài sản nhà nước trong ViewModel và ràng buộc các validations usercontrol cho những tiểu bang, sau đó trong CanExecute bạn có thể kiểm tra các giá trị của những tài sản hơn là cố gắng để ràng buộc với một usercontrol.

+0

Doobi, tiếng anh không phải là ngôn ngữ mẹ đẻ của tôi, tôi biết nó khá tệ hơn bình thường, vì vậy sự hiểu biết một phần không chính xác của bạn về bài đăng đầu tiên là lỗi của tôi, :) ViewModel cung cấp các lệnh, sử dụng các thuộc tính cũng được cung cấp bởi ViewModel. Thuộc tính đã được ràng buộc để xem kiểm soát và xác nhận lỗi được cung cấp thông qua IDataErrorInfo, mà implemetation là một phần của ViewModel quá. Mặc dù thực tế, trong Xem tất cả các giá trị lỗi được đánh dấu bằng mẫu đặc biệt, người dùng có thể thử gọi một lệnh ViewModel, sử dụng các thuộc tính có giá trị lỗi (hiện tại). Để chặn khả năng này, chúng tôi cột trong ICo –

+0

ICommand.Execute() kiểm tra tất cả các thuộc tính, giá trị nào được lệnh này sử dụng. Vì vậy, chúng tôi kiểm tra tính thích hợp ViewModel cho các lỗi hai lần: 1) trong chuỗi IDataErrorInfo.this [string propertyName] khi giá trị thuộc tính được thay đổi 2) trong ICommand.CanExecute khi WPF cập nhật giao diện người dùng Để tránh việc thực hiện (2) Tôi muốn truyền danh sách các điều khiển Xem (liên kết với các thuộc tính ViewModel, điều quan trọng đối với lệnh ViewModel hiện tại) trong ICommand.CanExecute như CommandParameter & kiểm tra lỗi qua Validation.GetHasError (DependencyObject). –

+0

Bởi vì Command receves danh sách DependencyObjects, ViewModel vẫn độc lập với View. Nhưng hôm nay, sau nhiều suy nghĩ tôi kết luận rằng cách tiếp cận của tôi giống như phát minh ra bánh xe hình vuông và tôi đã từ chối ý tưởng này. –

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