C# TextBoxInputMask避免空格
我正在尝试构建IP地址inputboxmask,如下所示: 我不喜欢的是数字之间的空格。我的问题是,如何防止数字之间出现空格,并强制用户写一个数字,而不是留下空格 行为类C# TextBoxInputMask避免空格,c#,xaml,C#,Xaml,我正在尝试构建IP地址inputboxmask,如下所示: 我不喜欢的是数字之间的空格。我的问题是,如何防止数字之间出现空格,并强制用户写一个数字,而不是留下空格 行为类 public class TextBoxInputMaskBehavior : Behavior<TextBox> { public MaskedTextProvider Provider { get; private set; } protected override
public class TextBoxInputMaskBehavior : Behavior<TextBox>
{
public MaskedTextProvider Provider { get; private set; }
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Loaded += AssociatedObjectLoaded;
AssociatedObject.PreviewTextInput += AssociatedObjectPreviewTextInput;
AssociatedObject.PreviewKeyDown += AssociatedObjectPreviewKeyDown;
DataObject.AddPastingHandler(AssociatedObject, Pasting);
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.Loaded -= AssociatedObjectLoaded;
AssociatedObject.PreviewTextInput -= AssociatedObjectPreviewTextInput;
AssociatedObject.PreviewKeyDown -= AssociatedObjectPreviewKeyDown;
DataObject.RemovePastingHandler(AssociatedObject, Pasting);
}
/*
Mask Character Accepts Required?
0 Digit (0-9) Required
9 Digit (0-9) or space Optional
# Digit (0-9) or space Required
L Letter (a-z, A-Z) Required
? Letter (a-z, A-Z) Optional
& Any character Required
C Any character Optional
A Alphanumeric (0-9, a-z, A-Z) Required
a Alphanumeric (0-9, a-z, A-Z) Optional
Space separator Required
. Decimal separator Required
, Group (thousands) separator Required
: Time separator Required
/ Date separator Required
$ Currency symbol Required
In addition, the following characters have special meaning:
Mask Character Meaning
< All subsequent characters are converted to lower case
> All subsequent characters are converted to upper case
| Terminates a previous < or >
\ Escape: treat the next character in the mask as literal text rather than a mask symbol
*/
private void AssociatedObjectLoaded(object sender, RoutedEventArgs e)
{
Provider = new MaskedTextProvider(InputMask, CultureInfo.CurrentCulture);
Provider.Set(AssociatedObject.Text);
Provider.PromptChar = PromptChar;
AssociatedObject.Text = Provider.ToDisplayString();
//seems the only way that the text is formatted correct, when source is updated
var textProp = DependencyPropertyDescriptor.FromProperty(TextBox.TextProperty, typeof (TextBox));
if (textProp != null)
{
textProp.AddValueChanged(AssociatedObject, (s, args) => UpdateText());
}
}
private void AssociatedObjectPreviewTextInput(object sender, TextCompositionEventArgs e)
{
TreatSelectedText();
var position = GetNextCharacterPosition(AssociatedObject.SelectionStart);
if (Keyboard.IsKeyToggled(Key.Insert))
{
if (Provider.Replace(e.Text, position))
position++;
}
else
{
if (Provider.InsertAt(e.Text, position))
position++;
}
position = GetNextCharacterPosition(position);
RefreshText(position);
e.Handled = true;
}
private void AssociatedObjectPreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Space) //handle the space
{
TreatSelectedText();
var position = GetNextCharacterPosition(AssociatedObject.SelectionStart);
if (Provider.InsertAt(" ", position))
RefreshText(position);
e.Handled = true;
}
if (e.Key == Key.Back) //handle the back space
{
if (TreatSelectedText())
{
RefreshText(AssociatedObject.SelectionStart);
}
else
{
if (AssociatedObject.SelectionStart != 0)
{
if (Provider.RemoveAt(AssociatedObject.SelectionStart - 1))
RefreshText(AssociatedObject.SelectionStart - 1);
}
}
e.Handled = true;
}
if (e.Key == Key.Delete) //handle the delete key
{
//treat selected text
if (TreatSelectedText())
{
RefreshText(AssociatedObject.SelectionStart);
}
else
{
if (Provider.RemoveAt(AssociatedObject.SelectionStart))
RefreshText(AssociatedObject.SelectionStart);
}
e.Handled = true;
}
}
/// <summary>
/// Pasting prüft ob korrekte Daten reingepastet werden
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Pasting(object sender, DataObjectPastingEventArgs e)
{
if (e.DataObject.GetDataPresent(typeof (string)))
{
var pastedText = (string) e.DataObject.GetData(typeof (string));
TreatSelectedText();
var position = GetNextCharacterPosition(AssociatedObject.SelectionStart);
if (Provider.InsertAt(pastedText, position))
{
RefreshText(position);
}
}
e.CancelCommand();
}
private void UpdateText()
{
//check Provider.Text + TextBox.Text
if (Provider.ToDisplayString().Equals(AssociatedObject.Text))
return;
//use provider to format
var success = Provider.Set(AssociatedObject.Text);
//ui and mvvm/codebehind should be in sync
SetText(success ? Provider.ToDisplayString() : AssociatedObject.Text);
}
/// <summary>
/// Falls eine Textauswahl vorliegt wird diese entsprechend behandelt.
/// </summary>
/// <returns>true Textauswahl behandelt wurde, ansonsten falls </returns>
private bool TreatSelectedText()
{
if (AssociatedObject.SelectionLength > 0)
{
return Provider.RemoveAt(AssociatedObject.SelectionStart,
AssociatedObject.SelectionStart + AssociatedObject.SelectionLength - 1);
}
return false;
}
private void RefreshText(int position)
{
SetText(Provider.ToDisplayString());
AssociatedObject.SelectionStart = position;
}
private void SetText(string text)
{
AssociatedObject.Text = string.IsNullOrWhiteSpace(text) ? string.Empty : text;
}
private int GetNextCharacterPosition(int startPosition)
{
var position = Provider.FindEditPositionFrom(startPosition, true);
if (position == -1)
return startPosition;
return position;
}
#region DependencyProperties
public static readonly DependencyProperty InputMaskProperty =
DependencyProperty.Register("InputMask", typeof (string), typeof (TextBoxInputMaskBehavior), null);
public string InputMask
{
get { return (string) GetValue(InputMaskProperty); }
set { SetValue(InputMaskProperty, value); }
}
public static readonly DependencyProperty PromptCharProperty =
DependencyProperty.Register("PromptChar", typeof (char), typeof (TextBoxInputMaskBehavior),
new PropertyMetadata('_'));
public char PromptChar
{
get { return (char) GetValue(PromptCharProperty); }
set { SetValue(PromptCharProperty, value); }
}
#endregion
}
公共类TextBoxInputMaskBehavior:行为
{
公共掩码TextProvider提供程序{get;private set;}
受保护的覆盖无效附加()
{
base.onatached();
AssociatedObject.Loaded+=AssociatedObjectLoaded;
AssociatedObject.PreviewTestInput+=AssociatedObjectPreviewTestInput;
AssociatedObject.PreviewKeyDown+=AssociatedObjectPreviewKeyDown;
AddPastingHandler(关联对象,粘贴);
}
附加时受保护的覆盖无效()
{
base.OnDetaching();
AssociatedObject.Loaded-=AssociatedObjectLoaded;
AssociatedObject.PreviewTestInput-=AssociatedObjectPreviewTestInput;
AssociatedObject.PreviewKeyDown-=AssociatedObjectPreviewKeyDown;
RemovePastingHandler(关联对象,粘贴);
}
/*
是否需要掩码字符?
需要0位数字(0-9)
9位(0-9)或空格可选
#需要数字(0-9)或空格
需要字母(a-z,a-z)
?字母(a-z,a-z)可选
&需要任何字符
C任意字符可选
需要字母数字(0-9,A-z,A-z)
字母数字(0-9,a-z,a-z)可选
需要空间分隔符
.需要小数点分隔符
,需要组(千)分隔符
:需要时间分隔符
/需要日期分隔符
需要$货币符号
此外,以下字符具有特殊含义:
掩码字符含义
<所有后续字符都转换为小写
>所有后续字符都转换为大写
|终止以前的<或>
\转义:将掩码中的下一个字符视为文字文本,而不是掩码符号
*/
已加载关联对象的私有void(对象发送方,RoutedEventArgs e)
{
Provider=新的MaskedTextProvider(InputMask,CultureInfo.CurrentCulture);
Provider.Set(AssociatedObject.Text);
Provider.PromptChar=PromptChar;
AssociatedObject.Text=Provider.ToDisplayString();
//在更新源代码时,似乎是文本格式正确的唯一方法
var textProp=dependencPropertyDescriptor.FromProperty(TextBox.TextProperty,typeof(TextBox));
如果(textProp!=null)
{
textProp.AddValueChanged(AssociatedObject,(s,args)=>UpdateText());
}
}
私有void AssociatedObjectPreviewTestInput(对象发送者,TextCompositionEventArgs e)
{
TreatSelectedText();
var position=GetNextCharacterPosition(AssociatedObject.SelectionStart);
如果(键盘.IsKeyToggled(键.插入))
{
if(提供者替换(如文本、位置))
位置++;
}
其他的
{
if(提供者插入(如文本、位置))
位置++;
}
位置=GetNextCharacterPosition(位置);
刷新文本(位置);
e、 已处理=正确;
}
private void AssociatedObjectPreviewKeyDown(对象发送方,KeyEventArgs e)
{
if(e.Key==Key.Space)//处理空格
{
TreatSelectedText();
var position=GetNextCharacterPosition(AssociatedObject.SelectionStart);
if(Provider.InsertAt(“,位置))
刷新文本(位置);
e、 已处理=正确;
}
if(e.Key==Key.Back)//处理Back空间
{
如果(TreatSelectedText())
{
刷新文本(AssociatedObject.SelectionStart);
}
其他的
{
如果(AssociatedObject.SelectionStart!=0)
{
if(Provider.RemoveAt(AssociatedObject.SelectionStart-1))
刷新文本(AssociatedObject.SelectionStart-1);
}
}
e、 已处理=正确;
}
if(e.Key==Key.Delete)//处理Delete键
{
//处理所选文本
如果(TreatSelectedText())
{
刷新文本(AssociatedObject.SelectionStart);
}
其他的
{
if(Provider.RemoveAt(AssociatedObject.SelectionStart))
刷新文本(AssociatedObject.SelectionStart);
}
e、 已处理=正确;
}
}
///
///粘贴prüft ob korrekte Daten reingpaste werden
///
///
///
私有无效粘贴(对象发送方、DataObjectPastingEventArgs e)
{
if(e.DataObject.GetDataPresent(typeof(string)))
{
var pastedText=(string)e.DataObject.GetData(typeof(string));
TreatSelectedText();
var position=GetNextCharacterPosition(AssociatedObject.SelectionStart);
if(提供者插入(粘贴文本,位置))
{
刷新文本(位置);
}
}
e、 取消命令();
}
私有void UpdateText()
{
//选中Provider.Text+TextBox.Text
if(Provider.ToDisplayString
<TextBox VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Grid.Row="6" Grid.Column="1" FontSize="22" >
<i:Interaction.Behaviors>
<behaviors:TextBoxInputMaskBehavior InputMask="{StaticResource InputMaskIp}" PromptChar="_" />
</i:Interaction.Behaviors>
</TextBox>