2011-09-28 10 views
12

Ho bisogno che la mia casella di testo sia di sola lettura. Tuttavia, quando imposto lo IsReadOnly su true, l'utente non può più interagire con la casella di testo utilizzando la tastiera poiché il cursore non viene più visualizzato.Casella di testo di sola lettura per WPF con cursore visibile (.NET 3.5)

In .NET 4 c'è una proprietà IsReadOnlyCaretVisible, tuttavia, sono obbligato a utilizzare .NET 3.5.

C'è una buona soluzione?

Grazie!

risposta

3

ho finito che farlo io con una proprietà allegato, lo fa il seguente:

  • Disabilita tutti gli input e la modifica alla casella di testo usando la tastiera
  • Imposta il menu contestuale di avere copia solo
  • Disabilita taglia/incolla comandi
  • modifica Disabilita mediante la selezione del mouse & trascinando
  • cambia il colore bacgrkound della casella di testo per notificare B eing di sola lettura.

Usage:

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

La classe:

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

Grazie per la soluzione, l'ho adottato per le mie esigenze e tutto funziona bene, ad eccezione del menu di scelta rapida! Continuo a ottenere il menu completo (Taglia, Copia, Incolla), riesci a pensare a qualche ragione per questo? – klawusel

10

utilizzo sia di questi nel vostro XAML

IsReadOnly="True" 
IsReadOnlyCaretVisible="True" 

IsReadOnlyCaretVisible funziona solo quando la prima proprietà è in uso.

+2

Questo va bene solo per .NET 4 ... – VitalyB

Problemi correlati