2013-05-29 59 views
16

Tôi có một WPF DataGridBắt WPF Data Grid Context Menu Bấm Row

<DataGrid AutoGenerateColumns="False" Name="dataGrid1" IsReadOnly="True" > 
<DataGrid.Columns> 
    <DataGridTextColumn Header="Site" Binding="{Binding Site}" Width="150" /> 
    <DataGridTextColumn Header="Subject" Binding="{Binding Subject}" Width="310" /> 
</DataGrid.Columns> 
<DataGrid.ContextMenu> 
    <ContextMenu> 
     <MenuItem Header="Delete" Click="Context_Delete"> 
      <MenuItem.Icon> 
       <Image Width="12" Height="12" Source="Images/Delete.png" /> 
      </MenuItem.Icon> 
     </MenuItem> 
    </ContextMenu> 
</DataGrid.ContextMenu> 
</DataGrid> 

Tôi có xử lý sự kiện click như:

private void Context_Delete(object sender, System.EventArgs e) { } 

Làm thế nào để tôi nhận được hàng mà Trình đơn ngữ cảnh là trước khi nhấp chuột? Đối tượng senderSystem.Windows.Controls.MenuItem, không phải là DataGridRow. Làm cách nào để nhận được DataGridRow nơi Trình đơn ngữ cảnh được nhấp vào. (Tôi đặt số DataGrid.ItemSource trong mã phía sau tệp.)

Trả lời

26

Vì vậy, dựa trên mã ví dụ của bạn, tôi đoán bạn ràng buộc DataGrid của bạn với một ObservableCollection của các đối tượng mà bạn ràng buộc các thuộc tính Site và Subject với DataGridColumns.

Về cơ bản, tất cả những gì bạn cần làm là tìm ra mục nào được ràng buộc với DataGridRow được nhấp vào và xóa mục đó khỏi ObservableCollection của bạn. Dưới đây là một số mã ví dụ để giúp bạn bắt đầu:

private void Context_Delete(object sender, RoutedEventArgs e) 
{ 
    //Get the clicked MenuItem 
    var menuItem = (MenuItem)sender; 

    //Get the ContextMenu to which the menuItem belongs 
    var contextMenu = (ContextMenu)menuItem.Parent; 

    //Find the placementTarget 
    var item = (DataGrid)contextMenu.PlacementTarget; 

    //Get the underlying item, that you cast to your object that is bound 
    //to the DataGrid (and has subject and state as property) 
    var toDeleteFromBindedList = (YourObject)item.SelectedCells[0].Item; 

    //Remove the toDeleteFromBindedList object from your ObservableCollection 
    yourObservableCollection.Remove(toDeleteFromBindedList); 
} 
+0

Cảm ơn bạn StevenHouben đã làm việc này một cách hoàn hảo! –

+0

Điều này đã cứu tôi khỏi một khoảnh khắc kéo tóc nặng. Nó hoạt động hoàn hảo. – coffeecoder

6

Thông thường, bạn không xử lý các hàng (nếu bạn làm - suy nghĩ lại về lý do) - thay vào đó bạn làm việc với mô hình xem. Khi bạn mở menu ngữ cảnh, bạn sẽ chọn mục của bạn, vì vậy nó có thể được truy cập thông qua thuộc tính DataGrid.SelectedItem. Tuy nhiên, nếu bạn thực sự cần DataGridRow - bạn có DataGrid.SelectedIndex của bạn và có rất nhiều câu trả lời ở đây trên SO về cách để có được hàng. như Get row in datagrid

+0

Cảm ơn bạn đã có ác ý. Tôi không có nhiều kiến ​​thức về WPF và cần phải đọc về nó một khi tôi nhận được thời gian. –

0

Để mở rộng điểm morincer của trên với một ví dụ, tôi đã kết thúc với một cách tiếp cận đơn giản hơn ...

private void MenuItem_OnClickRemoveSource(object sender, RoutedEventArgs e) 
{ 
    if (SourceDataGrid.SelectedItem == null) return; //safety first 

    _importViewModel.SourceList.Remove((SourceFileInfo)SourceDataGrid.SelectedItem); 
} 

Trong trường hợp của tôi,

_importViewModel.SourceList 

là ObservableCollection các hàng bị ràng buộc. Vì vậy, mỗi thực hành tốt nhất, tôi đơn giản xóa mục đã chọn khỏi bộ sưu tập và ràng buộc sẽ quản lý giao diện người dùng.

1

Câu trả lời của dsfgsho có hiệu quả đối với tôi, nhưng việc nhấp chuột phải vào hàng lưới sẽ không tự động chọn nó. Điều này có nghĩa là nếu tiêu điểm của bạn ở nơi khác và bạn nhấp chuột phải và chọn một mục menu ngữ cảnh, bạn có thể nhận được ngoại lệ ngoài phạm vi trên mục.SelectedCells [0] hoặc nếu bạn đã chọn hàng và nhấp chuột phải vào một mục khác hàng, bạn có thể nhận được kết quả không mong muốn.

Tôi xử lý điều này bằng cách xử lý "PreviewMouseRightButtonDown" trên DataGrid. Ở đây tôi chọn một hàng rõ ràng khi nó được nhấp chuột phải. Tôi quên nơi lớp UIHelpers của tôi đến từ đâu (có thể ở đâu đó trên trang này - tôi đã sử dụng nó để giải quyết các mục thả &), nhưng điều này sẽ hướng bạn đi đúng hướng nếu bạn gặp sự cố này. Đây là một phần mở rộng của câu trả lời được chấp nhận:

// handle right mouse click to select the correct item for context menu usage 
    private void myDataGrid_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     //find the clicked row 
     DataGridRow row = UIHelpers.TryFindFromPoint<DataGridRow>((UIElement) sender, e.GetPosition(myDataGrid)); 
     if (row == null) 
     { 
      Debug.WriteLine("Row is null"); 
      return; 
     } 
     else 
     { 
      Debug.WriteLine("Grid Row Index is " + row.GetIndex().ToString()); 
      (sender as DataGrid).SelectedIndex = row.GetIndex(); 
     } 
    } 
Các vấn đề liên quan