[英]What's the best way to create a WPF TextBox that replaces spaces with underscores?
我正在WPF中創建一個FilteredTextBox
,它包含所包含的TextBox
控件。 FilteredTextBox
必須只允許輸入[a-zA-Z0-9_]
范圍內的字符,並且我已經完成了那部分工作。 我已經連接到OnPreviewTextInput
來處理類型字符, OnPreviewDrop
用於過濾被拖放的字符,並且我添加了一個PreviewExecutedHandler,它在控件上執行命令時運行以處理粘貼。
到現在為止還挺好。
棘手的部分是控件還應該在輸入時用下划線替換空格。
我想出了一個解決方案,但它感覺很混亂,我不知道它缺少什么。 我覺得必須有一種我不知道的更好的技術。 我做了什么:
internal class FilteredTextBox : TextBox
{
public FilteredTextBox()
{
CommandManager.AddPreviewExecutedHandler(this, this.HandlePreviewExecuteHandler);
}
private void HandlePreviewExecuteHandler(object sender, ExecutedRoutedEventArgs e)
{
var uiCmd = e.Command as RoutedUICommand;
if (uiCmd != null && (uiCmd.Text == "Space" || uiCmd.Text == "ShiftSpace"))
{
// We're manually handling spaces, so we need to make appropriate checks.
if (this.Text.Length == this.MaxLength) return;
if (this.SelectionLength == 0)
{
// If the user is just typing a space normally
// We need to cache CaretIndex b/c it's reset to 0 when we set Text.
var tmpIndex = this.CaretIndex;
this.Text = this.Text.Insert(tmpIndex, "_");
this.CaretIndex = tmpIndex + 1;
}
else
{
// Otherwise, replace the selected text with the underscore and fixup the caret.
this.SelectedText = "_";
this.CaretIndex += this.SelectedText.Length;
this.SelectionLength = 0;
}
e.Handled = true; // If someone hits the spacebar, say we handled it.
return;
}
}
}
有更聰明的方法嗎?
我將TextBox
綁定到ValueConverter
,它按需消除空格並用下划線替換它們。
ValueConverter看起來像這樣:
public class SpaceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return System.Convert.ToString(value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
string text = System.Convert.ToString(value);
//the meat and potatoes is this line
text = text.Replace(" ", "_");
return text;
}
}
你的TextBox
會以這種方式綁定到它:
<TextBox Text="{Binding Path=UserString, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource SpaceConverter}}" />
請注意, UserString
必須位於當前的DataContext
。
不要忘記在XAML中定義SpaceConverter
。 假設您正在使用UserControl
,執行此操作的一種方法是:
<UserControl.Resources>
<local:SpaceConverter x:Key="SpaceConverter" />
</UserControl.Resources>
其中local
定義為包含SpaceConverter.cs的命名空間。
我認為你的邏輯很好,但是我把它放在OnPreviewKeyDown
的覆蓋中。
當控件失去焦點時,用_替換空格是否更好?或者當用戶將其鍵入時,您是否絕對需要更換空間?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.