0

I have a card textblock that I am using to show the user the card number:

<TextBlock x:Name="ccCard" Text="0000 0000 0000 0000" HorizontalAlignment="Center" 
Foreground="LightGray" FontFamily="Global Monospace" Grid.ColumnSpan="4" Margin="0,0,0,0.4" Width="200"/>

I have made it so that when a textbox has been written in, it types it into the textblock:

<TextBlock x:Name="ccCard" Text="0000 0000 0000 0000" HorizontalAlignment="Center" 
Foreground="LightGray" FontFamily="Global Monospace" Grid.ColumnSpan="4" Margin="0,0,0,0.4" 
Width="200"/>

I want to make it so it adds a space every 4 characters in the textblock, otherwise if it was a textbox I could use something like this:

Insert hyphen automatically after every 4 characters in a TextBox

How would I be able to do this?

HellFireElite
  • 39
  • 1
  • 7
  • Please show us what you have tried, what isn't working so we can help you out. As it's currently written, there's been no attempt at solving this; there can be numerous ways to accomplish this task. – Trevor Dec 27 '19 at 15:49
  • @Çöđěxěŕ I have no idea, thats what I need help with – HellFireElite Dec 27 '19 at 16:00
  • Let me get this straight. You have a `TextBox` and when a user types, you want to update a `TextBlock` with this including a space correct? Also `I have no idea`, are you talking about how to separate the string, how to update other controls when other data changes etc. please clarify exactly what you need help with. – Trevor Dec 27 '19 at 16:01
  • When the user types into the Textbox, the text is then put into the Textblock, I would like to add a " " every 4 characters, without separating the string – HellFireElite Dec 27 '19 at 16:04
  • 1
    Throw this in your class `private void txtBox_TextChanged(object sender, TextChangedEventArgs e) { ccCard.Text = string.Join(" ", Enumerable.Range(0, txtBox.Text.Length / 4).Select(i => txtBox.Text.Substring(i * 4, 4))); }`. Next make sure you have a textbox named: `txtBox` and it has a handler for `TextChanged` like : `TextChanged="txtBox_TextChanged"`. – Trevor Dec 27 '19 at 16:11
  • To be honest, there's many ways to do this, but you haven't shown us what you have tried so therefore we can only assume and throw out opinionated answers and or comments. – Trevor Dec 27 '19 at 16:13
  • yes it works, thanks – HellFireElite Dec 27 '19 at 16:14
  • you're welcome. Please remember next time to post what you have tried and what isn't working so we can better assist you. Also the comment above with code doesn't assume only numbers, if user types in a letter it would show as well. – Trevor Dec 27 '19 at 16:16
  • you're welcome, happy I could help. – Trevor Dec 27 '19 at 16:17

3 Answers3

1

For anyone wondering, as suggested by Çöđěxěŕ, the answer would look something like this:

ccCard.Text = string.Join(" ", Enumerable.Range(0, txtBox.Text.Length / 4).Select(i => txtBox.Text.Substring(i * 4, 4)));
HellFireElite
  • 39
  • 1
  • 7
0

You can create a Converter like this:

public class SeperatorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (targetType != typeof(string))
            throw new InvalidOperationException("The target must be a string");

        if (value != null)
        {
            var res = string.Join(" ",
                Enumerable.Range(0, value.ToString().Length / 4).Select(i => value.ToString().Substring(i * 4, 4)));

            return res;
        }

        return string.Empty;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

And for use this you should do this:

     <Window.Resources>
    <local:SeperatorConverter x:Key="seperatorConverter"/>
</Window.Resources>
<StackPanel>
    <TextBox Name="TextBox1" Width="200"/>
    <TextBlock Text="{Binding ElementName=TextBox1,Path=Text,Converter={StaticResource seperatorConverter}}"/></StackPanel>
Mahdi Asgari
  • 272
  • 1
  • 13
-1

Try following :

           string input = "0123456789012345678901234567890";
           string[] split = input.Select((x, i) => new { chr = x, index = i })
                .GroupBy(x => x.index / 4)
                .Select(x => string.Join("", x.Select(y => y.chr).ToArray()))
                .ToArray();
           string results = string.Join(" ", split);
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • 1
    An explanation of what is happening here and how it would solve the user's issue would be helpful, I am not seeing one. Also worth mentioning, this `linq` statement is inefficient IMHO. A simple enumerable with range and select would do... – Trevor Dec 27 '19 at 15:57
  • Which is more efficient yours or mine. With a very long string you method has to keep on counting from the beginning of the string. – jdweng Dec 27 '19 at 18:26
  • benchmark it? Also what about an explanation of your solution so the OP could understand? – Trevor Dec 27 '19 at 18:28