2011-09-28 9 views
12

テキストボックスは読み取り専用にする必要があります。しかし、IsReadOnlyに設定すると、カーソルはもはや表示されないため、キーボードを使用してテキストボックスと対話できなくなります。可視カーソル(.NET 3.5)を使用したWPFの読み取り専用テキストボックス

.NET 4には、IsReadOnlyCaretVisibleというプロパティがありますが、.NET 3.5を使用することを余儀なくされています。

良い解決策はありますか?

ありがとうございます!

答えて

3

私はそれが添付プロパティを使用して、それを自分自身をやって終了しましたが、それは次のようん:

  • キーボード
  • を使用して、テキストボックスに、すべての入力や修正を無効にのみ
  • コピーを持っているコンテキストメニューを設定します。
  • 無効カット/ペースト
  • がBに通知するテキストボックスのbacgrkound色を変更ドラッグマウス選択&を用い
  • 無効に変更を命令します読み取り専用です。

使用法:

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

クラス:

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

あなたのソリューションをありがとう、私は私のニーズに合わせて、すべての作品は、コンテキストメニューを除いて、それを採用!私は完全なメニュー(切り取り、コピー、貼り付け)を取得し続ける、あなたはこれの理由を考えることができますか? – klawusel

1

extracting the templates from .NET 4.0を試して、.NET 3.5アプリケーションで使用できます。

あまりにも多くの調整を加えることなく使用できたらうれしいことです。

10

使用これらの両方のあなたのXAMLで

IsReadOnly="True" 
IsReadOnlyCaretVisible="True" 

最初のプロパティが使用されているときIsReadOnlyCaretVisibleにのみ機能します。

+2

これは.NET 4にのみ有効です... – VitalyB

関連する問題