2011-09-28 27 views
12

Tôi cần hộp văn bản của mình là chỉ đọc. Tuy nhiên, khi tôi đặt IsReadOnly thành đúng, thì người dùng không thể tương tác với hộp văn bản bằng bàn phím nữa vì con trỏ không còn xuất hiện nữa.Hộp văn bản chỉ đọc cho WPF với con trỏ hiển thị (.NET 3.5)

Trong .NET 4 có thuộc tính IsReadOnlyCaretVisible, tuy nhiên, tôi buộc phải sử dụng .NET 3.5.

Có giải pháp tốt không?

Cảm ơn!

Trả lời

3

tôi đã kết thúc nó làm việc đó bản thân mình sử dụng một tài sản gắn liền, nó như sau:

  • Vô hiệu hóa tất cả các đầu vào và sửa đổi để các textbox sử dụng bàn phím
  • Sets menu ngữ cảnh để có Sao chép chỉ
  • Vô hiệu hóa cắt/dán lệnh
  • Vô hiệu hóa sửa đổi sử dụng lựa chọn chuột & kéo
  • Thay đổi màu bacgrkound của hộp văn bản để thông báo cho nó b eing chỉ đọc.

Cách sử dụng:

<TextBox AttachedProperties:ReadOnlyModeWithCursor.IsModeEnabled="True"> 
    This textbox has some long text and it can't be edited. 
</TextBox> 

Lớp:

public static class ReadOnlyModeWithCursor 
{ 
    public static readonly DependencyProperty IsModeEnabledProperty = DependencyProperty.RegisterAttached("IsModeEnabled", 
                              typeof(bool), 
                              typeof(ReadOnlyModeWithCursor), 
                              new FrameworkPropertyMetadata(OnModeEnabledChanged)); 

    private static ContextMenu _contextMenuWithCopyOnly = new ContextMenu(); 

    static ReadOnlyModeWithCursor() 
    { 
     _contextMenuWithCopyOnly.Items.Add(new MenuItem { Command = ApplicationCommands.Copy }); 
    } 

    public static bool GetIsModeEnabled(TextBox textBox) 
    { 
     if (textBox == null) 
     { 
      throw new ArgumentNullException("textBox"); 
     } 

     return (bool)textBox.GetValue(IsModeEnabledProperty); 
    } 

    public static void SetIsModeEnabled(TextBox textBox, bool value) 
    { 
     if (textBox == null) 
     { 
      throw new ArgumentNullException("textBox"); 
     } 

     textBox.SetValue(IsModeEnabledProperty, value); 
    } 

    private static void NoCutting(object sender, ExecutedRoutedEventArgs e) 
    { 
     if (e.Command == ApplicationCommands.Cut) 
     { 
      e.Handled = true; 
     } 
    } 

    private static void NoDragCopy(object sender, DataObjectCopyingEventArgs e) 
    { 
     if (e.IsDragDrop) 
     { 
      e.CancelCommand(); 
     } 
    } 

    private static void OnModeEnabledChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e) 
    { 
     var textBox = (TextBox)dependencyObject; 
     var isEnabled = (bool)e.NewValue; 

     if (isEnabled) 
     { 
      textBox.PreviewTextInput += textBox_PreviewTextInput; 
      textBox.PreviewKeyDown += textBox_PreviewKeyDown; 
      DataObject.AddPastingHandler(textBox, Pasting); 
      DataObject.AddCopyingHandler(textBox, NoDragCopy); 
      CommandManager.AddPreviewExecutedHandler(textBox, NoCutting); 

      // Default context menu has cut & paste, we want only copy. 
      textBox.ContextMenu = _contextMenuWithCopyOnly; 

      // Remove if you want to set the style of readonly textboxes via styles 
      textBox.Background = new SolidColorBrush(Color.FromRgb(240, 240, 240)); 
     } 
     else 
     { 
      textBox.PreviewTextInput -= textBox_PreviewTextInput; 
      textBox.PreviewKeyDown -= textBox_PreviewKeyDown; 
      DataObject.RemovePastingHandler(textBox, Pasting); 
      DataObject.RemoveCopyingHandler(textBox, NoDragCopy); 
      CommandManager.RemovePreviewExecutedHandler(textBox, NoCutting); 

      textBox.ClearValue(TextBox.ContextMenuProperty); 
      textBox.ClearValue(TextBox.BackgroundProperty); 
     } 
    } 

    private static void Pasting(object sender, DataObjectPastingEventArgs e) 
    { 
     e.CancelCommand(); 
    } 

    private static void textBox_PreviewKeyDown(object sender, KeyEventArgs e) 
    { 
     //pressing space doesn't raise PreviewTextInput, reasons here http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/446ec083-04c8-43f2-89dc-1e2521a31f6b?prof=required 
     if (e.Key == Key.Space || e.Key == Key.Back || e.Key == Key.Delete) 
     { 
      e.Handled = true; 
     } 
    } 

    private static void textBox_PreviewTextInput(object sender, TextCompositionEventArgs e) 
    { 
     e.Handled = true; 
    } 
} 
+0

Cảm ơn giải pháp của bạn, tôi đã sử dụng nó cho các nhu cầu của mình và tất cả đều hoạt động tốt, ngoại trừ menu ngữ cảnh! Tôi tiếp tục nhận được menu đầy đủ (Cắt, Sao chép, Dán), bạn có thể nghĩ ra bất kỳ lý do nào cho điều này không? – klawusel

1

Bạn có thể thử extracting the templates from .NET 4.0 và sử dụng chúng trong ứng dụng .NET 3.5 của mình.

Hy vọng rằng bạn có thể sử dụng nó mà không cần quá nhiều điều chỉnh.

10

sử dụng cả hai trong XAML của bạn

IsReadOnly="True" 
IsReadOnlyCaretVisible="True" 

IsReadOnlyCaretVisible chỉ hoạt động khi các tài sản đầu tiên đang được sử dụng.

+2

Điều đó chỉ tốt cho .NET 4 ... – VitalyB

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