wpf - 如何跟踪 WPF 的 TextBox 中删除了哪个字符?

标签 wpf textbox wpf-controls

我想跟踪用户通过 Delete 或 BackSpace Key 删除了哪个字符。

我正在处理文本框的 TextBox_ChangedEvent。

我可以从 中提取删除的字符吗? TextChangedEventArgs e.更改如果是,我该怎么做?

我想限制用户从 TextBox 中删除任何字符。我希望用户只能删除两个字符(比如说“(”或“)”)

请建议。

最佳答案

您将在下面找到附加属性的代码,可以像这样使用它来防止从文本框中删除除“(”或“)”之外的任何内容,句号。

<TextBox my:TextBoxRestriction.RestrictDeleteTo="()" ... />

这将正确处理所有鼠标和键盘更新,例如:
  • 选择多个字符时使用 Delete 键
  • 使用退格键
  • 使用Ctrl-X 剪切
  • 单击菜单栏上的“剪切”按钮

  • 正因为如此,它比简单地拦截 PreviewKeyDown 要强大得多。

    这也通过直接分配给 .Text 属性来禁用任何字节“(”或“)”的删除,因此这将失败:
    textBox.Text = "Good morning";
    

    因此,TextBoxRestriction 类还包含另一个名为 的附加属性。无限制文本 设置后,它能够绕过限制更新 Text 属性。这可以使用 TextBoxRestriction.SetUnrestrictedText 在代码中设置,或者像这样的数据绑定(bind):
    <TextBox my:TextBoxRestriction.RestrictDeleteTo="()"
             my:TextBoxRestriction.UnrestrictedText="{Binding PropertyNameHere}" />
    

    在下面的实现中,UnrestrictedText 仅在同时设置了 RestrictDeleteTo 时才有效。可以进行一个完整的实现,即在设置任一属性时注册事件处理程序,并将处理程序保存在第三个附加属性中以供以后注销。但是对于您当前的需求,这可能是不必要的。

    这是 promise 的实现:
    public class TextBoxRestriction : DependencyObject
    {
      // RestrictDeleteTo:  Set this to the characters that may be deleted
      public static string GetRestrictDeleteTo(DependencyObject obj) { return (string)obj.GetValue(RestrictDeleteToProperty); }
      public static void SetRestrictDeleteTo(DependencyObject obj, string value) { obj.SetValue(RestrictDeleteToProperty, value); }
      public static readonly DependencyProperty RestrictDeleteToProperty = DependencyProperty.RegisterAttached("RestrictDeleteTo", typeof(string), typeof(TextBoxRestriction), new PropertyMetadata
      {
        PropertyChangedCallback = (obj, e) =>
          {
            var box = (TextBox)obj;
            box.TextChanged += (obj2, changeEvent) =>
              {
                var oldText = GetUnrestrictedText(box);
                var allowedChars = GetRestrictDeleteTo(box);
                if(box.Text==oldText || allowdChars==null) return;
    
                foreach(var change in changeEvent.Changes)
                  if(change.RemovedLength>0)
                  {
                    string deleted = box.Text.Substring(change.Offset, change.RemovedLength);
                    if(deleted.Any(ch => !allowedChars.Contains(ch)))
                      box.Text = oldText;
                  }
                SetUnrestrictedText(box, box.Text);
              };
          }
      });
    
      // UnrestrictedText:  Bind or access this property to update the Text property bypassing all restrictions
      public static string GetUnrestrictedText(DependencyObject obj) { return (string)obj.GetValue(UnrestrictedTextProperty); }
      public static void SetUnrestrictedText(DependencyObject obj, string value) { obj.SetValue(UnrestrictedTextProperty, value); }
      public static readonly DependencyProperty UnrestrictedTextProperty = DependencyProperty.RegisterAttached("UnrestrictedText", typeof(string), typeof(TextBoxRestriction), new PropertyMetadata
      {
        DefaultValue = "",
        PropertyChangedCallback = (obj, e) =>
          {
            var box = (TextBox)obj;
            box.Text = (string)e.NewValue;
          }
      });
    
    }
    

    工作原理:当您设置 UnrestrictedText 时,它会设置 Text,反之亦然。 TextChanged 处理程序检查 Text 是否不同于 UnrestrictedText。如果是这样,它知道 Text 已通过设置 UnrestrictedText 以外的其他机制更新,因此会扫描更改以查找非法删除。如果找到,它将 Text 设置回仍存储在 UnrestrictedText 中的值,从而阻止更改。

    关于wpf - 如何跟踪 WPF 的 TextBox 中删除了哪个字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3051590/

    相关文章:

    c# - 当 selectedItem 为 null 时,在 Combobox 中显示 "Select an item"

    c# - 匿名委托(delegate)关闭窗口

    wpf - 如何使用MVVM在代码中将新网格添加到网格中

    regex - 尝试检查输入文本框的时间

    .net - 如何将全局异常处理添加到加载项dll?

    c# - Silverlight 到 WPF 转换器

    wpf - 绑定(bind)字符串格式

    c# - 无法从 ListView 中的文本框中获取文本

    c# - 向 TextBox 添加静态文本

    c# - 如何在wpf中自动调整富文本框的大小?