c# – TextBox并不总是更新
我有以下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"); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |