I have several WPF TextBoxes in my application that will be used for specifying file names. I'm looking for a solution that will quickly and easily allow me to disallow special characters (i.e. "\ / : ? " < > |") from being entered into these textboxes, without having to create a custom control that inherits from TextBox and doesn't require the use of Regular Expressions.
Asked
Active
Viewed 521 times
1 Answers
4
I created a static class called "DisallowSpecialCharatersTextBoxBehavior" that that harnesses the power of Attachable Properties in WPF, like so:
public static class DisallowSpecialCharactersTextboxBehavior
{
public static DependencyProperty DisallowSpecialCharactersProperty =
DependencyProperty.RegisterAttached("DisallowSpecialCharacters", typeof(bool), typeof(DisallowSpecialCharactersTextboxBehavior), new PropertyMetadata(DisallowSpecialCharactersChanged));
public static void SetDisallowSpecialCharacters(TextBox textBox, bool disallow)
{
textBox.SetValue(DisallowSpecialCharactersProperty, disallow);
}
public static bool GetDisallowSpecialCharacters(TextBox textBox)
{
return (bool)textBox.GetValue(DisallowSpecialCharactersProperty);
}
private static void DisallowSpecialCharactersChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var tb = dependencyObject as TextBox;
if (tb != null)
{
if ((bool)e.NewValue)
{
tb.PreviewTextInput += tb_PreviewTextInput;
tb.AddHandler(DataObject.PastingEvent, new DataObjectPastingEventHandler(tb_Pasting));
}
else
{
tb.PreviewTextInput -= tb_PreviewTextInput;
tb.RemoveHandler(DataObject.PastingEvent, new DataObjectPastingEventHandler(tb_Pasting));
}
}
}
private static void tb_Pasting(object sender, DataObjectPastingEventArgs e)
{
var pastedText = e.DataObject.GetData(typeof(string)) as string;
Path.GetInvalidFileNameChars().ToList().ForEach(c =>
{
if (pastedText.Contains(c))
{
e.CancelCommand();
}
});
}
private static void tb_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
{
if (Path.GetInvalidFileNameChars().ToList().ConvertAll(x => x.ToString()).Contains(e.Text))
{
e.Handled = true;
}
}
}
It can easily be applied to any TextBox in WPF like so:
<Window x:Class="ExampleApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ExampleApp"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBox local:DisallowSpecialCharactersTextboxBehavior.DisallowSpecialCharacters="true" />
</Grid>
</Window>

Ryan
- 1,300
- 12
- 29
-
I don't believe this handles the case where the user pastes data in the text box. Also, PreviewTextInput does not fire when spaces are input so if you ever wanted to block spaces you'd have to use some other mechanism like PreviewKeyDown. – Mike Zboray Jun 14 '14 at 03:28
-
@mikez: Actually , this does handle pasting, also, I don't want to block spaces, since it's a legal character for file names. – Ryan Jun 16 '14 at 17:59
-
It does not handle pasted text. Also, if you want to block invalid file name characters you should block all of the characters in `Path.GetInvalidFileNameChars()`. – Mike Zboray Jun 16 '14 at 18:13
-
@mikez Thank you for pointing this this out! I will use the Path.GetInvalidFileNameChars, and by the way, you're correct; it doesn't handle pasting correctly as it will allow backslashes or whatever else. I will come up with a different solution. – Ryan Jun 16 '14 at 19:03
-
@mikez Mike, please check out the edit I just now made to my answer. Not only am I using the Path.GetInvalidFileNameChars, but I'm also handling pasting as well. – Ryan Jun 16 '14 at 19:51