2009-03-09 34 views
9

Tôi có cửa sổ ghi nhật ký dữ liệu chỉ đọc mà tôi đã triển khai bằng cách sử dụng kiểm soát RichTextBox. Tôi muốn có thể vô hiệu hóa tính năng tự động kiểm tra xảy ra khi người dùng nhấp vào trong điều khiển để người dùng có thể chọn nhật ký cụ thể cho hoạt động sao chép/dán hoặc bất kỳ điều gì. Tuy nhiên, ngay sau khi người dùng nhấp vào RichTextBox, nó sẽ tự động cuộn xuống dưới cùng, khiến việc này trở nên khó khăn.Ngăn chặn Tự động kiểm tra trong RichTextBox

Bất kỳ ai biết cách ghi đè hành vi này?

Cảm ơn!

Trả lời

6

Bạn có thể có một cái nhìn tại làm một cái gì đó như thế này:

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
private static extern IntPtr LockWindowUpdate(IntPtr Handle); 

sau đó trong phương pháp của bạn mà gắn thêm dữ liệu log (Tôi đang làm cho một số giả định ở đây), bạn có thể làm điều gì đó như thế này:

LockWindowUpdate(this.Handle); 
int pos = richTextBox1.SelectionStart; 
int len = richTextBox1.SelectionLength; 
richTextBox1.AppendText(yourText); 
richTextBox1.SelectionStart = pos; 
richTextBox1.SelectionLength = len; 
LockWindowUpdate(IntPtr.Zero); 

Tôi đã làm một ứng dụng thử nghiệm nhỏ với bộ hẹn giờ đã gắn thêm vào hộp richtextbox và nó dừng nó khỏi cuộn để tôi có thể chọn văn bản. Nó có một số vấn đề vị trí và không hoàn hảo, nhưng có lẽ nó sẽ giúp bạn hướng tới một giải pháp của riêng bạn.

Tất cả tốt nhất!

11

Điều khiển RichTextBox tự động cuộn đến lựa chọn hiện tại, nếu vùng chọn không bị ẩn. RichTextBox.AppendText(), ngoài việc thêm văn bản, cũng sửa đổi lựa chọn hiện tại, và do đó gián tiếp kích hoạt hành vi "autoscrolling". Lưu ý rằng nếu RichTextBox.HideSelection được đặt thành true, thì lựa chọn sẽ bị ẩn khi điều khiển không được lấy nét; điều này giải thích hành vi bạn đã mô tả, trong đó tính năng tự động kiểm tra chỉ xảy ra khi người dùng nhấp vào kiểm soát. (Do đó cho phép nó tập trung) Để tránh điều này, bạn cần phải làm như sau khi nối văn bản:

  1. Sao lưu lựa chọn ban đầu
  2. Không tập trung kiểm soát
  3. Ẩn lựa chọn (thông qua một thông điệp Windows)
  4. AppendText
  5. Khôi phục lựa chọn ban đầu
  6. Unhide lựa chọn
  7. Trung lọc kiểm soát

Bạn cũng có thể kiểm tra xem lựa chọn đã ở cuối văn bản hay chưa và cho phép hành vi tự động kiểm tra nếu nó - về cơ bản mô phỏng hành vi của cửa sổ đầu ra của Visual Studio. Ví dụ:

[System.Runtime.InteropServices.DllImport("user32.dll")] 
    static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam); 
    const int WM_USER = 0x400; 
    const int EM_HIDESELECTION = WM_USER + 63; 

    void OnAppend(string text) 
    { 
     bool focused = richTextBox1.Focused; 
     //backup initial selection 
     int selection = richTextBox1.SelectionStart; 
     int length = richTextBox1.SelectionLength; 
     //allow autoscroll if selection is at end of text 
     bool autoscroll = (selection==richTextBox1.Text.Length); 

     if (!autoscroll) 
     { 
      //shift focus from RichTextBox to some other control 
      if (focused) textBox1.Focus(); 
      //hide selection 
      SendMessage(richTextBox1.Handle, EM_HIDESELECTION, 1, 0); 
     } 

     richTextBox1.AppendText(text); 

     if (!autoscroll) 
     { 
      //restore initial selection 
      richTextBox1.SelectionStart = selection; 
      richTextBox1.SelectionLength = length; 
      //unhide selection 
      SendMessage(richTextBox1.Handle, EM_HIDESELECTION, 0, 0); 
      //restore focus to RichTextBox 
      if(focused) richTextBox1.Focus(); 
     } 
    } 
+0

Giải pháp của bạn hoạt động như một sự quyến rũ! Tôi đã thử rất nhiều cách tiếp cận khác để ngăn RichTextBox của tôi di chuyển sau khi thực hiện thay đổi định dạng và đây là cách duy nhất hoạt động. Nó có vẻ phức tạp lúc đầu, nhưng nó đã làm việc :) –

0

Giải pháp của SytS có vấn đề, khi một số văn bản được "nối thêm", thanh cuộn di chuyển đến phần đầu của bảng điều khiển. Một giải pháp là để lưu/khôi phục lại vị trí cuộn với:

[System.Runtime.InteropServices.DllImport("User32.dll")] 
    extern static int GetScrollPos(IntPtr hWnd, int nBar); 

    [System.Runtime.InteropServices.DllImport("user32.dll")] 
    static extern int SetScrollPos(IntPtr hWnd, int nBar, int nPos, bool bRedraw); 

This solution là đầy đủ hơn cho tôi.

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