加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – TextBox并不总是更新

发布时间:2020-12-15 05:39:34 所属栏目:百科 来源:网络整理
导读:我有以下TextBox: TextBox Text="{Binding SearchString,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" / 绑定到以下属性: private string _searchString;public string SearchString{ get { return _searchString; } set { value = Regex.Replace(v
我有以下TextBox:
<TextBox Text="{Binding SearchString,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />

绑定到以下属性:

private string _searchString;
public string SearchString
{
    get 
    { 
        return _searchString; 
    }
    set
    {
        value = Regex.Replace(value,"[^0-9]",string.Empty);             
        _searchString = value;
        DoNotifyPropertyChanged("SearchString");
    }
}

该类继承自实现INotifyPropertyChanged的基类

public event PropertyChangedEventHandler PropertyChanged;
protected void DoNotifyPropertyChanged(string propertyName)
{
    if (PropertyChanged != null) 
        PropertyChanged(this,new PropertyChangedEventArgs(propertyName));
}

我只想要一个快速而肮脏的方法来禁止非整数文本框的非数字字符(我知道它不完整,只是为了演示).我不想仅仅通知有非法文本或任何内容,我想立即丢弃所有不允许输入的字符.

但是,TextBox表现得很奇怪.我仍然可以输入我想要的任何文字,它将显示为输入,例如“1AAA”.即使在此示例中已将属性正确清除为“1”,文本框仍显示“1aaa”.只有当我输入一个会导致_searchString更改的实际数字时,它才会更新显示的文本,例如当我有“1aaa2”时它会正确地更新为“12”.这是怎么回事?

解决方法

这听起来像特定于视图的逻辑,所以我认为没有理由不使用代码隐藏视图来控制它.我个人会在TextBox上使用PreviewKeyDown实现这种行为,丢弃任何非数字字符.

拥有一些可以重复使用的泛型,例如自定义NumbersOnlyTextBox控件,或者你可以附加到TextBox的AttachedProperty来指定它只允许数字,这可能不会有什么坏处.

事实上,我记得创建了一个附加属性,允许您为文本框指定正则表达式,并且它将字符输入限制为该正则表达式.我有一段时间没有使用它,所以你可能想测试它或者可能更新它,但这是代码.

// When set to a Regex,the TextBox will only accept characters that match the RegEx
#region AllowedCharactersRegex Property

/// <summary>
/// Lets you enter a RegexPattern of what characters are allowed as input in a TextBox
/// </summary>
public static readonly DependencyProperty AllowedCharactersRegexProperty =
    DependencyProperty.RegisterAttached("AllowedCharactersRegex",typeof(string),typeof(TextBoxProperties),new UIPropertyMetadata(null,AllowedCharactersRegexChanged));

// Get
public static string GetAllowedCharactersRegex(DependencyObject obj)
{
    return (string)obj.GetValue(AllowedCharactersRegexProperty);
}

// Set
public static void SetAllowedCharactersRegex(DependencyObject obj,string value)
{
    obj.SetValue(AllowedCharactersRegexProperty,value);
}

// Events
public static void AllowedCharactersRegexChanged(DependencyObject obj,DependencyPropertyChangedEventArgs e)
{
    var tb = obj as TextBox;
    if (tb != null)
    {
        if (e.NewValue != null)
        {
            tb.PreviewTextInput += Textbox_PreviewTextChanged;
            DataObject.AddPastingHandler(tb,TextBox_OnPaste);
        }
        else
        {
            tb.PreviewTextInput -= Textbox_PreviewTextChanged;
            DataObject.RemovePastingHandler(tb,TextBox_OnPaste);
        }
    }
}

public static void TextBox_OnPaste(object sender,DataObjectPastingEventArgs e)
{
    var tb = sender as TextBox;

    bool isText = e.SourceDataObject.GetDataPresent(DataFormats.Text,true);
    if (!isText) return;

    var newText = e.SourceDataObject.GetData(DataFormats.Text) as string;
    string re = GetAllowedCharactersRegex(tb);
    re = "[^" + re + "]";

    if (Regex.IsMatch(newText.Trim(),re,RegexOptions.IgnoreCase))
    {
        e.CancelCommand();
    }
}

public static void Textbox_PreviewTextChanged(object sender,TextCompositionEventArgs e)
{
    var tb = sender as TextBox;
    if (tb != null)
    {
        string re = GetAllowedCharactersRegex(tb);
        re = "[^" + re + "]";

        if (Regex.IsMatch(e.Text,RegexOptions.IgnoreCase))
        {
            e.Handled = true;
        }
    }
}

#endregion // AllowedCharactersRegex Property

它会像这样使用:

<TextBox Text="{Binding SearchString,UpdateSourceTrigger=PropertyChanged}" 
         local:TextBoxHelpers.AllowedCharactersRegex="[0-9]" />

但至于为什么它不会更新UI. UI知道该值实际上没有更改,因此在收到PropertyChange通知时不会重新评估绑定.

为了解决这个问题,你可以尝试暂时将值设置为其他值,然后再将其设置为正则表达式值,然后引发PropertyChange通知,以便UI重新评估绑定,但老实说这并不是一个理想的解决方案.

private string _searchString;
public string SearchString
{
    get 
    { 
        return _searchString; 
    }
    set
    {
        value = Regex.Replace(value,string.Empty);    

        // If regex value is the same as the existing value,// change value to null to force bindings to re-evaluate
        if (_searchString == value)
        {
            _searchString = null;
            DoNotifyPropertyChanged("SearchString");
        }

        _searchString = value;
        DoNotifyPropertyChanged("SearchString");
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读