2011-07-26 33 views
8

Tôi đã nghiên cứu điều này và đang stumped: Tôi có một DataGrid WPF, và sử dụng một mô hình MVVM. Tôi muốn, trong một số trường hợp, ngăn chặn khả năng thay đổi một hàng trong DataGrid. Tôi đã nghiên cứu điều này và đã thử các kỹ thuật giống như kỹ thuật được tìm thấy here. Trong thực tế, công trình này, tuy nhiên có một 'nhấp nháy' không mong muốn (nó chọn hàng được nhấp một lúc rồi quay trở lại lựa chọn trước đó), trong khi đây là giải pháp gần tôi muốn có một cách thanh lịch hơn chẳng hạn như ngăn chặn thay đổi hàng ngay từ đầu.ngăn ngừa thay đổi hàng trong datagrid

Tôi ngạc nhiên rằng không phải là một lựa chọnChuyển đổi hoặc BeforeSelectionChanged vì vậy tôi có thể hủy bỏ sự kiện từ bắn; và ngăn chặn sự thay đổi chỉ số trong mô hình xem của tôi dường như không tạo ra bất kỳ sự khác biệt nào.

Làm thế nào tôi có thể làm điều này?

Cảm ơn bạn.

Trả lời

5

điều gì sẽ xảy ra nếu bạn thực hiện các sự kiện previewkeydownpreviewmousedown và chỉ cần gọi e.Handled=true trong trường hợp nhất định của bạn?

Edit: để đáp ứng các MVVM phong cách: bạn có thể tạo một Behavior với một DependencyProperty bạn có thể ràng buộc hoàn cảnh của bạn để. trong hành vi này, bạn có thể xử lý các sự kiện và có thể một số nội dung khác, như người dùng nhấp vào dữ liệu hoặc tiêu đề ...

+0

Đề xuất trước đây hoạt động hoàn hảo (mặc dù đề xuất sau đây là một đề xuất rất thú vị và tôi cũng đã cân nhắc dùng thử) - Cảm ơn bạn. – Mani5556

2

DispatcherPriority đã được đặt thành ContextIdle. Điều này làm cho bạn có nhấp nháy, kể từ khi SelectedItem của bạn được thiết lập hai lần (và nó được trả lại hai lần). Chỉ cần đặt mức độ ưu tiên thành Bình thường và bạn sẽ không nhấp nháy nữa.

+0

Điều này đã giúp tôi, cảm ơn bạn. –

0

Có một số ví dụ cho phương pháp PreviewMouseDown here.

Thỏa thuận chung là đảo ngược DataGrid.SelectedItem về giá trị ban đầu của nó bên trong trình xử lý SelectionChanged của datagrid không hoạt động như mong đợi; tất cả các ví dụ mã dường như làm việc trì hoãn việc đảo ngược bằng cách yêu cầu Dispatcher lên lịch cho nó sau này.

Bạn có CellStyle trên DataGrid của mình không? Đối với tôi, sau đây làm việc:

XAML:

<DataGrid.CellStyle> 
    <Style TargetType="{x:Type DataGridCell}"> 
     <Style.Triggers> 
      <Trigger Property="IsSelected" Value="True"> 
       <Setter Property="Background" Value="DarkSlateBlue"/> 
       <Setter Property="Foreground" Value="White"/> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
</DataGrid.CellStyle> 

codebehind:

private void MyDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    if (e.AddedItems.Count > 0) 
    { 
     object x = e.AddedItems[0]; 
     if (x is MyObjectType && x != myViewModel.CurrentItem && 
      myViewModel.ShouldNotDeselectCurrentItem()) 
     { 
      // this will actually revert the SelectedItem correctly, but it won't highlight the correct (old) row. 
      this.MyDataGrid.SelectedItem = null; 
      this.MyDataGrid.SelectedItem = myViewModel.CurrentItem; 
     } 
    } 
} 

Điểm là trường hợp SelectedCellsChanged sa thải sau sự kiện SelectionChanged - và đặc biệt, đó là thiết lập SelectedItem không cập nhật chính xác SelectedCells là thuộc tính chỉ đọc, do đó, thêm codebehind:

private void MyDataGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e) 
{ 
    List<DataGridCellInfo> selectedCells = MyDataGrid.SelectedCells.ToList(); 

    List<MyObjectType> wrongObjects = selectedCells.Select(cellInfo => cellInfo.Item as MyObjectType) 
     .Where (myObject => myObject != myViewModel.CurrentItem).Distinct().ToList(); 
    if (wrongObjects.Count > 0) 
    { 
     MyDataGrid.UnselectAllCells(); 
     MyDataGrid.SelectedItem = null; 
     MyDataGrid.SelectedItem = myViewModel.CurrentItem; 
    } 
} 

Rõ ràng, các trình xử lý cần phải được nối với các sự kiện tương ứng trên lưới dữ liệu.

Điều này hoạt động như mong đợi, đã hủy đúng thay đổi lựa chọn nếu muốn và không tạo ra nhấp nháy.

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