将TextChanged函数放入一个类中,供多个TextBox使用

时间:2014-06-16 08:58:20

标签: c# wpf

我有一个应用程序,主要用于捕获大多数数值。 通常我使用的是文本框。为了组织这个文本,我决定对输入的数字进行分组,并在组之间放置空格。

像'555555555'这样的东西会显示为'555 555 555',类似于whatsapp或viber注册文本框效果。我正在使用TextChanged事件来完成此任务。

这是我迄今为止如何做到这一点的一个例子。这是一个接收电话号码的文本框。

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;
    }

问题是这个初学者的代码太长了所以我不能把它放在需要分开数字的每个文本框中(我的讲师已经提到重复这样的事情是不好的做法,我可能会受到惩罚它)。但是我有很多细胞需要能够做到这一点,但我缺乏将其转化为行为或将其置于类中并使其仍然起作用的技能。

所以基本上我想知道的是你如何在一个get,set类或行为类(或者我忽略的任何其他事情)中实现它,以便在多个页面中使用。建议任何人?

4 个答案:

答案 0 :(得分:1)

您应该从cell_TextChanged中提取代码并将其移至新方法中。然后,您将在事件处理程序中调用此新方法。

e.g。

private void cell_TextChanged(object sender, TextChangedEventArgs e)
{
    YourTextChangedHandlerMethod(sender as TextBox, e);
}

这种方法意味着您不必为每个事件编写相同的代码 - 您只需重用相同的代码即可。 YourTextChangedHandlerMethod的第一个参数将是引发事件的文本框。

您可能会发现可以收紧新方法所需的参数,但这对您来说应该很容易理解。

答案 1 :(得分:1)

将一些代码封装到任何UI控件中的最简单方法是声明一个附加属性......这几乎就是它们的用途 - 扩展预先存在的UI元素的功能。如果您不熟悉附加属性,则可以从MSDN上的Attached Properties Overview页面了解有关它们的更多信息。

以下是您可以使用的示例...您需要做的就是添加事件处理程序:

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" ... />

答案 2 :(得分:0)

如果您想以MVVM方式执行此操作,可以使用以下任何选项:

1。 绑定到不同的属性并在ViewModel中调用相同的方法。不要忘记指定UpdateSourceTrigger

<TextBox Text="{Binding MyText, ElementName=myControl, UpdateSourceTrigger=PropertyChanged}"/>

2。 或者为TextBoxes编写自己的附加行为以支持TextChanged命令。

3。 或者使用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>

答案 3 :(得分:0)

如果您没有关注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;
                }
            }

        }

    }

并在您的主窗口中加载

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    
    }