简体   繁体   English

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

[英]putting a TextChanged function into a class for multiple TextBoxes to use

I have an application that's meant to do data capturing of mostly numerical values. 我有一个应用程序,旨在进行大多数数值的数据捕获。 Typically I'm using text boxes. 通常,我使用文本框。 To organise this text, I decided to group the digits entered and put spaces between the groups. 为了整理这段文字,我决定将输入的数字分组,并在各组之间放置空格。

So something like '555555555' will appear like '555 555 555', to give something similar to a whatsapp or viber signup text box effect. 因此,类似于“ 555555555”的内容将类似于“ 555 555 555”的内容,以提供类似于whatsapp或viber注册文本框效果的内容。 I'm using a TextChanged event to accomplish this. 我正在使用TextChanged事件来完成此操作。

Here's an example of how I've done it so far. 这是到目前为止我如何做的一个例子。 This is a Text Box ment to take in a phone number. 这是输入电话号码的文本框。

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

the problem is this code for starters is too long so I can't afford to place it in every text box that needs to separate numbers (My lecturer already mentioned repetition of something like this was bad practice and I might get penalised for it). 问题是入门代码太长了,因此我无法将其放在每个需要分隔数字的文本框中(我的讲师已经提到重复这样的事情是不好的做法,我可能会因此受到惩罚)。 However I have a lot of cells that need to be able to do this but I kind of lack the skill to turn it into a behaviour or place it in a class and make it still function. 但是,我有很多需要执行此操作的单元,但是我缺乏将其转变为行为或将其置于类中并使其仍然起作用的技能。

So basically what I'd like to know is how you'd implement this in a get,set class or behaviour class (or anyother I'm overlooking for that matter) to be used across multiple pages. 因此,基本上我想知道的是您如何在get,set类或行为类(或我为此忽略的其他任何类)中实现此方法,以用于多个页面。 Suggestions anyone? 建议有人吗?

You should extract the code from cell_TextChanged and move it into a new method. 您应该从cell_TextChanged提取代码并将其移至新方法中。 You would then call this new method in your event handlers. 然后,您将在事件处理程序中调用此新方法。

eg 例如

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

This approach means you don't have to write the same code for each event - you just reuse the same code. 这种方法意味着您不必为每个事件编写相同的代码-您只需重复使用相同的代码即可。 The first parameter to YourTextChangedHandlerMethod will be the text box that raised the event. YourTextChangedHandlerMethod的第一个参数将是引发事件的文本框。

You may find you can tighten the parameters your new method takes, but that should be simple for you to figure out. 您可能会发现可以收紧新方法采用的参数,但这对您来说应该很简单。

The simplest way of encapsulating some code into any UI control is to declare an Attached Property... that's pretty much what they're there for - extending the functionality of pre-existing UI elements. 将某些代码封装到任何UI控件中的最简单方法是声明一个Attached属性...这几乎就是它们的作用-扩展预先存在的UI元素的功能。 If you're not familiar with Attached Properties, then you can find out more about them from the Attached Properties Overview page on MSDN. 如果您不熟悉附加属性,则可以从MSDN上的“ 附加属性概述”页面中找到有关它们的更多信息。

Here is an example that you could use... all you need to do is to add your event handler: 这是一个示例,您可以使用...所有您需要做的就是添加事件处理程序:

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

It should be added into a class named TextBoxProperties and would be used as simply as this: 应该将其添加到名为TextBoxProperties的类中,并以如下方式简单使用:

<TextBox TextBoxProperties:IsFormatted="True" ... />

If you want to do it in MVVM way you can use any of those options : 如果要以MVVM方式进行操作,则可以使用以下任何选项:

1. Bind to different properties and in ViewModel call the same method. 1.绑定到不同的属性,并在ViewModel中调用相同的方法。 Do not forget to specify UpdateSourceTrigger 不要忘记指定UpdateSourceTrigger

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

2. Or write your own an attached behavior for TextBoxes to support TextChanged commands. 2.或者编写您自己的TextBoxes附加行为以支持TextChanged命令。

3. Or use InvokeCommandAction from System.Windows.Interactivity to bind to the same method 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>

If you are not following MVVM then you can use something like this. 如果您不遵循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;
                }
            }

        }

    }

and in your mainwindow Loaded 并在您的主窗口中加载

mainwindow.xaml 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    
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM