C# 将TextChanged函数放入类中以供多个文本框使用
我有一个应用程序,主要用来捕获数值数据。 通常我使用文本框。为了组织这篇文章,我决定将输入的数字分组,并在分组之间留出空格 所以像“5555555”这样的东西会像“5555555”一样出现,以提供类似whatsapp或viber注册文本框的效果。我正在使用TextChanged事件来完成此操作 这里有一个我到目前为止是如何做到这一点的例子。这是一个用于输入电话号码的文本框C# 将TextChanged函数放入类中以供多个文本框使用,c#,wpf,C#,Wpf,我有一个应用程序,主要用来捕获数值数据。 通常我使用文本框。为了组织这篇文章,我决定将输入的数字分组,并在分组之间留出空格 所以像“5555555”这样的东西会像“5555555”一样出现,以提供类似whatsapp或viber注册文本框的效果。我正在使用TextChanged事件来完成此操作 这里有一个我到目前为止是如何做到这一点的例子。这是一个用于输入电话号码的文本框 private void cell_TextChanged(object sender, TextChangedEventA
private void cell_TextChanged(object sender, TextChangedEventArgs e)
{
string phrase = cell.Text;
if (phrase != null)
{
// This is to reset all spaces in the text back to none before the code below puts new ones.
// This avoids puting a space directly next to another one previously set.
// For some reason the textbox becomes difficult to work with if I don't do this.
phrase = Regex.Replace(phrase, @"\s+", "");
}
// If the text is smaller than 4 characters;
if (phrase.Length <= 4)
{
// Do nothing to it
cell.Text = phrase;
}
// if the text is equal to five characters
if (phrase.Length == 5)
{
// group the first 3 characters
string first = phrase.Substring(0, 3);
// and the last 2 to characters
string second = phrase.Substring(3, 2);
// then put a space between them
string paste = (first + " " + second);
//This string goes into the TextBox 'cell'
cell.Text = paste;
}
// if the text is equal to six characters
if (phrase.Length == 6)
{
// group the first 3 characters
string first = phrase.Substring(0, 3);
//And the last 3 characters
string second = phrase.Substring(3, 3);
// then put a space between them
string paste = (first + " " + second);
//This string goes into the TextBox 'cell'
cell.Text = paste;
}
if (phrase.Length == 7)
{
// group the first 4 characters
string first = phrase.Substring(0, 4);
// then the next 3
string second = phrase.Substring(4, 3);
// then put a space between them
string paste = (first + " " + second);
//This string goes into the TextBox 'cell'
cell.Text = paste;
}
if (phrase.Length == 8)
{
// group the first 4 characters
string first = phrase.Substring(0, 4);
// then the next 3
string second = phrase.Substring(4, 3);
// then the next character
string third = phrase.Substring(7, 1);
// then put a space between the first, second and third string
string paste = (first + " " + second + " " + third);
//This string goes into the TextBox 'cell'
cell.Text = paste;
}
if (phrase.Length == 9)
{
// group the first 4 characters
string first = phrase.Substring(0, 4);
// then the next 3
string second = phrase.Substring(4, 3);
// then the next 2 characters
string third = phrase.Substring(7, 2);
// then put a space between the first, second and third string
string paste = (first + " " + second + " " + third);
//This string goes into the TextBox 'cell'
cell.Text = paste;
}
if (phrase.Length == 10)
{
// group the first 4 characters
string first = phrase.Substring(0, 4);
// then the next 3
string second = phrase.Substring(4, 3);
// then the next 3 characters after that
string third = phrase.Substring(7, 3);
// then put a space between the first, second and third string
string paste = (first + " " + second + " " + third);
//This string goes into the TextBox 'cell'
cell.Text = paste;
}
//This is to keep the cursor at the end of the TextBox's text when I enter a new character other wise it goes back to the start.
cell.CaretIndex = cell.Text.Length;
}
private void cell\u TextChanged(对象发送方,textchangedventargs e)
{
字符串短语=cell.Text;
if(短语!=null)
{
//这是在下面的代码放入新空格之前,将文本中的所有空格重置为无。
//这样可以避免将一个空格直接放在先前设置的另一个空格旁边。
//由于某种原因,如果我不这样做,文本框将变得很难使用。
短语=Regex.Replace(短语@“\s+”,“”);
}
//如果文本小于4个字符;
如果(phrase.Length您应该从cell_TextChanged
中提取代码,并将其移动到一个新方法中。然后在事件处理程序中调用此新方法
e、 g
这种方法意味着您不必为每个事件编写相同的代码,只需重复使用相同的代码。YourTextChangedHandlerMethod
的第一个参数是引发事件的文本框
您可能会发现,您可以收紧新方法所采用的参数,但这对您来说应该很简单。如果您想以MVVM的方式执行此操作,您可以使用以下任何选项:
一,。
绑定到不同的属性并在ViewModel中调用相同的方法。不要忘记指定UpdateSourceTrigger
<TextBox Text="{Binding MyText, ElementName=myControl, UpdateSourceTrigger=PropertyChanged}"/>
2.
或者为文本框编写自己的附加行为,以支持TextChanged命令
三,。
或者使用System.Windows.Interactivity中的InvokeCommandAction绑定到同一方法
<TextBox x:Name="SomeText">
<interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="TextChanged">
<interactivity:InvokeCommandAction Command="{Binding SomeCommand, Mode=OneWay}"/>
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>
</TextBox>
如果您没有遵循MVVM,那么您可以使用类似的方法
class FindingLogicalChildren
{
public static IEnumerable<T> FindVisualChildren<T>(DependencyObject dependencyObject) where T : DependencyObject
{
if (dependencyObject != null)
{
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
{
DependencyObject child = VisualTreeHelper.GetChild(dependencyObject, i);
if (child != null && child is T)
{
yield return (T)child;
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
类查找逻辑儿童
{
公共静态IEnumerable FindVisualChildren(DependencyObject DependencyObject),其中T:DependencyObject
{
if(dependencyObject!=null)
{
for(int i=0;i
并在主窗口中加载
mainwindow.xaml
private void window_Loaded(object sender, RoutedEventArgs e)
{
foreach (TextBox it in FindingLogicalChildren.FindVisualChildren<TextBox>(Application.Current.MainWindow))
{
t = it;
t.TextChanged += t_TextChanged;
}
}
void t_TextChanged(object sender, TextChangedEventArgs e)
{
// do your work here.. you get all textchanged events here
}
private void window\u已加载(对象发送方,路由目标)
{
foreach(在FindingLogicalChildren.FindVisualChildren(Application.Current.MainWindow)中的文本框)
{
t=它;
t、 TextChanged+=t_TextChanged;
}
}
void t_TextChanged(对象发送方,textchangedventargs e)
{
//在这里做你的工作。你在这里得到所有的文本更改事件
}
将某些代码封装到任何UI控件中的最简单方法是声明附加属性…这正是它们的作用所在-扩展预先存在的UI元素的功能。如果您不熟悉附加属性,则可以从MSDN上的页面了解有关附加属性的更多信息
下面是一个您可以使用的示例…您只需添加事件处理程序:
public static readonly DependencyProperty IsFormattedProperty = DependencyProperty.RegisterAttached("IsFormatted", typeof(bool), typeof(TextBoxProperties), new UIPropertyMetadata(default(bool), OnIsFormattedChanged));
public static bool GetIsFormatted(DependencyObject dependencyObject)
{
return (bool)dependencyObject.GetValue(IsFormattedProperty);
}
public static void SetIsFormatted(DependencyObject dependencyObject, bool value)
{
dependencyObject.SetValue(IsFormattedProperty, value);
}
public static void OnIsFormattedChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
TextBox textBox = dependencyObject as TextBox;
if (textBox != null)
{
bool newIsFormattedValue = (bool)dependencyPropertyChangedEventArgs.NewValue;
if (newIsFormattedValue) textBox.TextChanged += YourTextChangedHandler;
else textBox.TextChanged -= YourTextChangedHandler;
}
}
应将其添加到名为TextBoxProperties
的类中,使用方法如下:
<TextBox TextBoxProperties:IsFormatted="True" ... />
<代码>将代码提取到一个单独的方法中,并从处理程序调用该方法。如果您的需求适合,考虑在MVVM方法中这样做,它也会提高性能。这可能对您有帮助:<代码>为(int i=3;i<s长度;i+=4){s= s插入(s长度-i),“”);}
您希望用户以后自己修改这些分组吗?例如,如果用户备份到一个空格并手动删除它,会发生什么情况?好的,我听到了。问题是,我如何告诉新方法接受来自任何文本框的文本,而不仅仅是cell.text?我如何告诉它应该将字符串“粘贴”返回到textbox触发了它?我只是对答案做了一个小的更新,希望能有所帮助。sender
参数是引发事件的控件,因此它不关心哪个文本框引发了事件,只关心它正在处理一个文本框。显然,在新方法中,您应该将cell
重命名为更通用的名称。嗨。Another问题。我如何将“sender”中的值传递给字符串“phrase”?在它是string phrase=cell.Text
之前。似乎string phrase=sender
不起作用,sender.ToString
cast也不起作用……我想我还是不明白。抱歉,如果我问的问题应该是更明显的。我很抱歉当您提到将“cell”重命名为Offer try(发送者为文本框)时,我猜您可能是指这个.Text@DanielKelley我可以确认你的代码是有效的。我刚刚发现Sheridan的代码更容易在以后的其他页面上实现。尽管如此,我还是很感激。如果我没有先弄明白这一点,它就不会起作用了。我想你不需要使用交互性,对于文本更改,你可以在Propertychanged上使用UpdateSourceRigger。你可以使用其中任何一种se三个选项:)。编辑答案。选项2为我做了。谢谢。嗨。如果我可以问一下,我该如何定义事件?我已经尝试了public void YourTextChangedHandler(object sender,TextChangedEventHandler routedEventArgs)
和public void Yo
<TextBox TextBoxProperties:IsFormatted="True" ... />