2009-03-24 36 views
32

Tôi muốn cho phép người dùng đánh dấu một hàng trên DataFrid WPF và nhấn phím xóa để xóa hàng.Sự kiện "nhấn phím xóa" cho DataGrid WPF là gì?

  • các chức năng đã là được xây dựng vào UI của lưới điện, vì vậy cho người dùng, hàng biến mất
  • Tôi hiện xử lý này trên các sự kiện SelectionChanged (mã dưới đây)
  • Tôi lặp qua tất cả các "e.RemovedItems" và xóa chúng với LINQ

vấn đề là: ngay cả khi bạn chỉ đơn giản là se Bài giảng một hàng và di chuyển ra khỏi nó, thay đổi lựa chọn được bắn và hàng đó là trong e.RemovedItems (đó là lẻ, tại sao chỉ đơn giản là chọn một cái gì đó đặt nó trong một container RemovedItems?).

Vì vậy, tôi đang tìm kiếm một sự kiện DeleteKeyPressed để tôi có thể dễ dàng xử lý sự kiện. Sự kiện đó được gọi là gì?

Tôi đang sử dụng bộ công cụ tháng 3 năm 2009.

XAML:

<Grid DockPanel.Dock="Bottom"> 
    <toolkit:DataGrid x:Name="TheDataGrid" 
         SelectionChanged="TheDataGrid_SelectionChanged" 
         AutoGenerateColumns="True" 
         RowEditEnding="TheDataGrid_RowEditEnding"/> 

code-behind:

private void TheDataGrid_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) 
{ 
    if (e.RemovedItems.Count > 0) 
    { 
     Message.Text = "The following were removed: "; 
     foreach (object obj in e.RemovedItems) 
     { 
      Customer customer = obj as Customer; 
      Message.Text += customer.ContactName + ","; 
      _db.Order_Details.DeleteAllOnSubmit(
       customer.Orders.SelectMany(o => o.Order_Details)); 
      _db.Orders.DeleteAllOnSubmit(customer.Orders); 
      _db.Customers.DeleteOnSubmit(customer); 
     } 
    } 

    try 
    { 
     _db.SubmitChanges(); 
    } 
    catch (Exception ex) 
    { 
     Message.Text = ex.Message; 
    } 
} 

ĐÁP:

Cảm ơn lnferis, đó là chính xác những gì tôi đang tìm kiếm, đây là sự kiện xử lý xóa xong của tôi cho DataGrid, lưu ý sự kiện KeyDown không kích hoạt vì một số lý do.

XAML:

<toolkit:DataGrid x:Name="TheDataGrid" 
        KeyDown="TheDataGrid_KeyDown" 
        PreviewKeyDown="TheDataGrid_PreviewKeyDown" 
        AutoGenerateColumns="True" 
        RowEditEnding="TheDataGrid_RowEditEnding"/> 

code-behind

private void TheDataGrid_PreviewKeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.Delete) 
    { 
     var grid = (DataGrid)sender; 

     if (grid.SelectedItems.Count > 0) 
     { 
      string checkMessage = "The following will be removed: "; 

      foreach (var row in grid.SelectedItems) 
      { 
       Customer customer = row as Customer; 
       checkMessage += customer.ContactName + ","; 
      } 
      checkMessage = Regex.Replace(checkMessage, ",$", ""); 

      var result = MessageBox.Show(checkMessage, "Delete", MessageBoxButton.OKCancel); 
      if (result == MessageBoxResult.OK) 
      { 
       foreach (var row in grid.SelectedItems) 
       { 
        Customer customer = row as Customer; 
        _db.Order_Details.DeleteAllOnSubmit(
         customer.Orders.SelectMany(o => o.Order_Details)); 
        _db.Orders.DeleteAllOnSubmit(customer.Orders); 
        _db.Customers.DeleteOnSubmit(customer); 
       } 
       _db.SubmitChanges(); 
      } 
      else 
      { 
       foreach (var row in grid.SelectedItems) 
       { 
        Customer customer = row as Customer; 
        LoadData(); 
        _db.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, customer); //TODO: this doesn't refresh the datagrid like the other instance in this code 
       } 
      } 
     } 
    } 
} 

private void TheDataGrid_KeyDown(object sender, KeyEventArgs e) 
{ 
    Console.WriteLine("never gets here for some reason"); 
} 
+3

KeyDown không bao giờ nên đến đây vì nó đã xử lý (e.Handled = true) trong trình xử lý trước đó trong bong bóng. – Shimmy

Trả lời

25

Các RemovedItems mục phản ánh các mục gỡ bỏ từ việc lựa chọn, chứ không phải từ lưới điện.

Xử lý sự kiện PreviewKeyDown, và sử dụng SelectedItems tài sản để xóa các hàng được lựa chọn có:

private void PreviewKeyDownHandler(object sender, KeyEventArgs e) { 
    var grid = (DataGrid)sender; 
    if (Key.Delete == e.Key) { 
     foreach (var row in grid.SelectedItems) { 
      ... // perform linq stuff to delete here 
     } 
    } 
} 
+3

Có lý do gì khiến DataGrid không chỉ có sự kiện RowsDeleted? WPF, theo mặc định, đồ họa loại bỏ hàng khi bạn bấm phím xóa. Vì vậy, nó đã làm logic này và lặp qua các hàng đã xóa. Tại sao họ không thể thêm vào một trình xử lý sự kiện để tôi không phải sao chép mã này và kiểm tra các khóa. – Chad

+16

Đây không phải là rất tốt đẹp, nếu bạn đang chỉnh sửa một ô và sử dụng phím xóa để loại bỏ một số ký tự trong ô, bạn sẽ xóa toàn bộ hàng. – epalm

+2

@epalm nếu bạn thêm mã 'foreach' vào bên trong' if (grid.SelectedItems.Count> 0) 'giống như Edward Tanguay, thì mọi thứ sẽ hoạt động. Nhưng cảm ơn vì đã chỉ ra! –

-1

Bạn muốn để xử lý các sự kiện KeyUp hoặc KeyDown và kiểm tra Key ép cho Delete.

private void OnKeyDown(object sender, KeyEventArgs e) { 
    if (Key.Delete == e.Key) { 
    // Delete pressed 
    } 
} 
+5

sự kiện KeyDown không kích hoạt khi tôi nhấn phím (lẻ), PreviewKeyDown hoạt động mặc dù –

17

bạn đang ràng buộc gì DataGrid của bạn để? Lý tưởng nhất, bạn nên phản ứng với các sự kiện CollectionChanged trên bộ sưu tập mà bạn đang ràng buộc. Bằng cách đó, logic của bạn (xóa các mục đã xóa) sẽ được tách khỏi giao diện người dùng của bạn.

Bạn có thể xây dựng một bộ sưu tập có thể quan sát chứa các đối tượng của bạn và liên kết nó với ItemsSource chỉ vì mục đích đó nếu bộ sưu tập gốc không có các sự kiện cần thiết.

Nó có thể không phù hợp với thiết lập cụ thể của bạn, nhưng đó là cách tôi thường làm điều đó.

+0

Tôi hoàn toàn đồng ý với cách tiếp cận này. Một ObservableCollection cho phép ViewModel của bạn xử lý bất kỳ thay đổi nào đối với nguồn dữ liệu bên dưới. Bạn không cần phải dựa vào code-behind ... không có gì sai lầm với việc thực hiện nó thông qua code-behind ... chỉ cần dọn dẹp bằng cách sử dụng ViewModel. –

3

Vui lòng thực hiện theo mã bên dưới. Tôi đã thành công với mã bên dưới.

Vui lòng cho tôi biết nếu có thay đổi.

private void grdEmployee_PreviewKeyDown(object sender, KeyEventArgs e) 
    { 

     if (e.Device.Target.GetType().Name == "DataGridCell") 
     { 
      if (e.Key == Key.Delete) 
      { 
       MessageBoxResult res = MessageBox.Show("Are you sure want to delete?", "Confirmation!", MessageBoxButton.YesNo,MessageBoxImage.Question); 
       e.Handled = (res == MessageBoxResult.No); 
      } 
     } 
    } 
7

XAML

<DataGrid ItemsSource="{Binding}" CommandManager.PreviewCanExecute="Grid_PreviewCanExecute" /> 

Mã đằng sau

private void Grid_PreviewCanExecute(object sender, CanExecuteRoutedEventArgs e) 
{ 
    DataGrid grid = (DataGrid)sender; 
    if (e.Command == DataGrid.DeleteCommand) 
    { 
    if (MessageBox.Show(String.Format("Would you like to delete {0}", (grid.SelectedItem as Person).FirstName), "Confirm Delete", MessageBoxButton.OKCancel) != MessageBoxResult.OK) 
     e.Handled = true; 
    } 
} 
0

Một chút muộn để đảng, nhưng để có được Inferis câu trả lời làm việc:

Dim isEditing = False 
AddHandler dg.BeginningEdit, Sub() isEditing = True 
AddHandler dg.RowEditEnding, Sub() isEditing = False 
AddHandler dg.PreviewKeyDown, Sub(obj, ev) 
    If e.Key = Key.Delete AndAlso Not isEditing Then ... 

này epalms sửa bình luận: "nếu bạn đang chỉnh sửa ô và sử dụng phím xóa để xóa một số ký tự trong ô, bạn sẽ xóa toàn bộ hàng "

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