只读文本框,用于具有可见光标的WPF.NET 3.5)

本文关键字:WPF 光标 NET 文本 用于 只读 | 更新日期: 2023-09-27 18:10:06

我需要我的文本框为只读。然而,当我将IsReadOnly设置为true时,由于光标不再出现,用户不能再使用键盘与文本框进行交互。

在。net 4中有一个IsReadOnlyCaretVisible属性,然而,我被迫使用。net 3.5

有好的解决方案吗?

谢谢!

只读文本框,用于具有可见光标的WPF.NET 3.5)

在您的XAML

中使用这两种方法
IsReadOnly="True"
IsReadOnlyCaretVisible="True" 

IsReadOnlyCaretVisible仅在第一个属性被使用时起作用。

我已经用附加属性结束了它,它做了以下事情:

  • 禁止使用键盘输入和修改文本框
  • 将上下文菜单设置为只复制
  • 禁用剪切/粘贴命令
  • 禁止使用鼠标选择&拖着
  • 改变文本框的背景色,以通知文本框为只读。

用法:

<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;
    }
}

你可以尝试从。net 4.0中提取模板,并在你的。net 3.5应用程序中使用它们。