2009-02-24 39 views
17

Tôi đang sử dụng mẫu M-V-VM trong một ứng dụng WPF. Tôi ràng buộc một ViewModel đến một ContentControl và sử dụng một mẫu dữ liệu được định nghĩa trong tài nguyên cửa sổ để hiển thị khung nhìn (một UserControl) cho ViewModel đó.Ràng buộc với một lệnh trong một DataGrid

Trong ViewModel, tôi có một bộ sưu tập các mục. Tôi đang ràng buộc bộ sưu tập đó vào lưới dữ liệu được cung cấp trong bộ công cụ WPF. Cũng trong mô hình khung nhìn, tôi có một lệnh RemoveItem được định nghĩa để lấy một đối số cho ID mục cần xóa.

Làm cách nào để liên kết với lệnh đó trong lưới dữ liệu? Ngữ cảnh dữ liệu của lưới là bộ sưu tập, vì vậy, chẳng hạn như:

<Button Command="{Binding Path=RemoveCommand}" CommandParameter="{Binding Path=id}">X</Button> 

không hoạt động - không thể tìm thấy lệnh. Tôi nghĩ rằng tôi cần phải làm RelativeSource ràng buộc, nhưng nó sẽ trông như thế nào? Loại tổ tiên có phải là UserControl hay ContentControl không? ViewModel của tôi ở đâu là DataContext?

Hoặc tôi có phải ra khỏi đây không?

Trả lời

36

Vâng, bạn chỉ cần tăng cấp một. Tôi muốn thử ràng buộc với ElementName trước và chỉ đến RelativeSource nếu cần. Ví dụ, tôi muốn này:

<DataGrid x:Name="_grid"> 
    ... 
     <Button Command="{Binding DataContext.RemoveItem, ElementName=_grid}"/> 
    ... 
</DataGrid> 

Điều đó nói rằng, trình biên dịch XAML có thể nhận được quần lót của nó trong một hôn khi nói đến tên phần tử và Phạm vi trong điều khiển, vì vậy bạn có thể cần phải dùng đến một RelativeSource:

<DataGrid x:Name="_grid"> 
    ... 
    <Button Command="{Binding DataContext.RemoveItem, 
        RelativeSource={RelativeSource FindAncestor, 
            AncestorType={x:Type DataGrid}} 
        }"/> 
    ... 
</DataGrid> 

Bạn chỉ cần tìm kiếm cho đến khi bối cảnh dữ liệu là mô hình chế độ xem của bạn. Bạn có thể tìm kiếm một UserControl nếu bạn muốn - không chắc nó thực sự quan trọng. Cả hai đều là những ràng buộc khá dễ vỡ, đó là lý do tại sao tôi thích cách tiếp cận ElementName.

+0

Tuyệt vời. Cảm ơn, Kent! –

+1

Chào mừng bạn. Một cách khác để làm điều này là để lộ một bộ sưu tập các mô hình xem con chứ không phải là một tập hợp các mục dữ liệu. Sau đó, các mô hình xem con đó có thể có một thuộc tính để hiển thị lệnh, giúp bạn tránh được việc giới thiệu các ràng buộc dễ vỡ như thế này. –

+0

Cảm ơn bạn đã giải quyết được vấn đề của tôi. –

1

Tôi muốn xác định mô hình chế độ xem trong datacontext của điều khiển bằng tên ViewModel. Việc ràng buộc dễ viết hơn bằng cách sử dụng ElementName

... 
<UserControl.DataContext> 
    <local:UserControlViewModel x:Name="ViewModel"/> 
</UserControl.DataContext> 
... 

... 
<DataGridTemplateColumn Width="30"> 
    <DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <Button Command="{Binding RemoveCommand, ElementName=ViewModel}" 
        CommandParameter="{Binding}">Remove</Button> 
     </DataTemplate> 
    </DataGridTemplateColumn.CellTemplate> 
</DataGridTemplateColumn> 
... 

Lưu ý rằng trong trường hợp này tham số lệnh là đối tượng dữ liệu toàn bộ của hàng. Đôi khi tốt hơn

CommandParameter="{Binding Id}" 

vì bạn không phải tìm lại dữ liệu.

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