2015-05-07 13 views
12

Tôi có một keyPressed tín hiệu trong Gtk #/mono C# cho hai mục đích khác nhau mà không có mặt trong các mặc định TreeView: a) đi đến các tế bào tiếp theo bằng cách nhấn TAB, và b) bắt đầu chỉnh sửa bằng cách nhấn phím bất kỳ.Làm cách nào để quản lý các thao tác nhấn phím cho các mục đích đặc biệt trong Gtk # TreeView?

Các TreeView rất đơn giản, nó có một ListStore chỉ hiển thị các hàng và cột, tức là nó chứa dữ liệu dạng bảng.

Mã tôi có bên dưới.

[GLib.ConnectBefore] 
protected void OnTableKeyPressed(object o, Gtk.KeyPressEventArgs args) 
{ 
    int rowIndex; 
    int colIndex; 

    // Do not "eat" the key, by default 
    args.RetVal = false; 

    // Get the current position, needed in both cases. 
    this.GetCurrentCell(out rowIndex, out colIndex); 

    // Adapt the column 
    colIndex += NumFixedColumns; 

    if (args.Event.Key != Gdk.Key.ISO_Enter) { 
     if (args.Event.Key == Gdk.Key.Tab 
      || args.Event.Key == Gdk.Key.ISO_Left_Tab) 
     { 
      if(args.Event.State == Gdk.ModifierType.ShiftMask) { 
       // Back 
       colIndex -= 1; 
       if (colIndex < 1) { 
        colIndex = document.Columns; 
        --rowIndex; 
       } 

       rowIndex = Math.Max(0, rowIndex); 
      } else { 
       // Advance 
       colIndex += 1; 
       if (colIndex > document.Columns) { 
        colIndex = 1; 
        ++rowIndex; 
       } 

       rowIndex = Math.Min(rowIndex, document.Rows); 
      } 

      this.SetCurrentCell(rowIndex, colIndex); 
      args.RetVal = true;        // Eat the TAB 
     } else { 
      this.SetCurrentCell(rowIndex, colIndex, true); 
     } 
    } 

    return; 
} 

Tôi có hai câu hỏi:

  1. Làm thế nào tôi có thể báo hiệu cho TreeView rằng một tế bào đã được hoàn tất chỉnh sửa? Vấn đề là nếu bạn nhấn TAB khi không có ô nào đang được chỉnh sửa, mọi thứ đều hoạt động tốt. Tuy nhiên, nếu người dùng đang chỉnh sửa ô thì nội dung đã nhập cho đến thời điểm này sẽ bị mất. Vì vậy, trong trường hợp người dùng đang chỉnh sửa ô, tôi muốn báo hiệu cho TreeView để hoàn tất ấn bản và thực hiện theo hành vi hiện tại.

  2. Làm cách nào để tránh mất khóa đầu tiên khi chỉnh sửa ô? Giả sử bạn đang ở trên một ô. Bạn nhấn các phím 1, 2, 3 và 4. Trình xử lý của tôi sẽ can thiệp chính xác và đặt ô hiện tại ở chế độ ấn bản. Tuy nhiên, ô chỉ nhận được 2, 3 và 4, mặc dù tôi đang đặt arg.RetVal thành false.

Thông tin về chức năng của tôi

  • GetCurrentCell(row, col) dịch tế bào hiện tại từ một TreePath để một cặp ints.
  • SetCurrentCell(row, col, [edit]) sử dụng TreeView.SetCursor() để tạo dòng điện. edit có thể là đúng hoặc false. Nếu đúng, thì ô sẽ được đưa vào phiên bản. Nếu nó là false, không có gì được chỉnh sửa.

Trả lời

2

Tôi không có chuyên gia về GTK, trên thực tế tôi chưa bao giờ làm việc với nó. Nhưng tôi đã chơi với các Điều khiển tiêu chuẩn để đánh lừa chúng thành hành vi không mặc định. Tôi đã đặc biệt sửa đổi thanh Menu, mà bị mắc kẹt tất cả các đầu vào khi phím Alt đã được nhấn, nhưng tôi cần phím Alt như một công cụ sửa đổi cho các tương tác khác nhau. Vì vậy, tôi có thể cung cấp cho bạn một số lời khuyên chung về việc lừa TreeView của bạn vào những gì bạn cần.

Câu hỏi 1:

Từ những gì bạn mô tả, tôi cho rằng hành vi mặc định sẽ được nhấn Enter cho một chỉnh sửa thành công, và rời khỏi di động hủy bỏ việc chỉnh sửa. Điều này có thể được chấp nhận trong nhiều ứng dụng. Những người khác (ví dụ: Microsoft Excel) có xu hướng chấp nhận chỉnh sửa ngay cả khi rời khỏi ô. Vì vậy, tôi có thể hiểu rằng bạn muốn hành vi đó.

Nếu không có hành vi tích hợp như vậy, bạn có thể mô phỏng Hành động mà người dùng phải thực hiện để báo hiệu TreeView để hoàn tất chỉnh sửa, ví dụ: nhấn Enter. Bạn có thể gửi sự kiện Khóa giả bằng cách sử dụng phương pháp được mô tả here hoặc nếu GTK xây dựng trên WPF như here. Cách tiếp cận thứ hai thậm chí còn thấp hơn vì nó thực sự cấy ghép sự kiện khóa giả trong hàng đợi sự kiện cửa sổ. Tôi đoán rằng nên làm việc trong mọi trường hợp, miễn là nền tảng của bạn là Windows. Nhưng tôi chắc rằng có những cơ chế tương tự trong các hệ điều hành khác.

Sau đó, chỉ sau đó, dịch sang ô kế tiếp, TreeView sẽ bị mất sự kiện tiêu điểm, nhưng nó không còn ở chế độ chỉnh sửa và không có gì xảy ra.

Câu hỏi 2:

Những gì tôi nghĩ sẽ xảy ra như sau: Một phím được nhấn, TreeView không có trong chế độ chỉnh sửa, vì vậy bỏ qua sự kiện này. Bạn nhận được sự kiện và đặt nó ở chế độ chỉnh sửa. Nhưng sau đó sự kiện sẽ không trở lại TreeView, vì vậy không có dữ liệu nhập nào được thực hiện nữa.

Bạn có thể thử phương pháp trên và gửi lại sự kiện chính theo cách thủ công. Một cách khác là nắm bắt sự kiện trước đó, sau đó khi TreeView xử lý sự kiện đó. Trong WPF thường có sự kiện PreviewOn* (ví dụ: xem here). vì vậy có thể có một sự kiện như vậy để kiểm soát của bạn?

Bạn cũng có thể tự móc mình sâu hơn. Trong WPF có sự kiện InputManager.Current.PreProcessInput nằm ngay phía trên vòng lặp thông báo của cửa sổ và cho phép bạn lọc và xử lý tất cả các loại đầu vào.

Đây là một snipped từ mã của tôi có thể giúp bạn:

InputManager.Current.PreProcessInput += (sender, e) => 
{ 
    if (e.StagingItem.Input is MouseButtonEventArgs) 
    { 
     var earg = (MouseButtonEventArgs)e.StagingItem.Input; 
     if (earg.RoutedEvent == Mouse.PreviewMouseDownOutsideCapturedElementEvent) 
      OnPreviewMouseDownOutsideCapturedElement(sender, earg); 
    } 
}; 

Đối móc lowlevel hơn xem ví dụ question này.

Chúc may mắn và vui lòng nhận xét, nếu bạn có câu hỏi cụ thể hơn.

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