티스토리 뷰

반응형
페이스북에 올라온 민원 해결을 위해서 간단하게 프로젝트를 만들었습니다.

Q. 텍스트박스에 숫자를 입력하면 자동으로 컴마를 찍어주고, 백스페이스를 누르면 삭제가 되도록 하고 싶습니다.~

A. 일단 여러분들이 의견 주셨습니다.

우선 컨버터를 이용한 방법이 이야기가 되어서, 저도 컨버터를 이용해서 처리를 할려고 해봤는데..

컨버터는 프로퍼티 체인지 이벤트가 발생했을 경우에 컨버터가 값을 변경해 주는 역할을 합니다...그런데.. TextBlock에는 뷰모델에서 변경된 내용을 바로 화면에 이쁘게 뿌려주는데.. 텍스트박스에서는 키가 입력되면, 그 내용을 바로 뷰모델에 값을 넣어주는 역할만을 하고, 프로퍼티가 변경된 내용을 화면에 다시 뿌려주지는 않습니다.

StringFormatConverter.cs

using System;
using Windows.UI.Xaml.Data;
namespace App1
{
    public class StringFormatConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            var format = parameter as string;
            if (!string.IsNullOrEmpty(format) && value is string)
            {
                int.TryParse(value.ToString(), out var number);
                return string.Format(format, number);
            }
            return value;
        }
        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            if (value == null) return null;
            int.TryParse(value.ToString().Replace(",", ""), out var number);
            return number.ToString();
        }
    }
}

음..그래서 결국 비헤이비어를 만들어서 처리를 해보았습니다.

NumberTextBoxBehavior.cs

using Windows.System;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Microsoft.Xaml.Interactivity;
namespace App1
{
    public class NumberTextBoxBehavior : Behavior<TextBox>
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.KeyUp += AssociatedObject_KeyUp;
        }
        private void AssociatedObject_KeyUp(object sender, KeyRoutedEventArgs e)
        {
            switch (e.Key)
            {
                case VirtualKey.Number0:
                case VirtualKey.Number1:
                case VirtualKey.Number2:
                case VirtualKey.Number3:
                case VirtualKey.Number4:
                case VirtualKey.Number5:
                case VirtualKey.Number6:
                case VirtualKey.Number7:
                case VirtualKey.Number8:
                case VirtualKey.Number9:
                case VirtualKey.Back:
                    var numberText = AssociatedObject.Text;
                    if (string.IsNullOrEmpty(numberText)) return;
                    var number = int.Parse(numberText.Replace(",", ""));
                    var formatString = string.Format("{0:N0}", number);
                    if (formatString != number.ToString())
                    {
                        AssociatedObject.Text = formatString;
                        AssociatedObject.SelectionStart = AssociatedObject.Text.Length;
                    }
                    break;
            }
        }
        protected override void OnDetaching()
        {
            AssociatedObject.KeyUp -= AssociatedObject_KeyUp;
            base.OnDetaching();
        }
    }
}


MainPage.xaml


<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:Custom="using:Microsoft.Xaml.Interactivity"
    x:Class="App1.MainPage"
    xmlns:converters="using:Microsoft.Toolkit.Uwp.UI.Converters"
    mc:Ignorable="d"
    x:Name="mainPage">
    <Page.Resources>
        <local:StringFormatConverter x:Key="StringFormatConverter" />
    </Page.Resources>
    <Page.DataContext>
        <local:MainPageViewModel />
    </Page.DataContext>

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
            <TextBox MinWidth="200" TextAlignment="Right"
                     Text="{Binding Number, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                <Custom:Interaction.Behaviors>
                    <local:NumberTextBoxBehavior />
                </Custom:Interaction.Behaviors>
            </TextBox>

            <TextBlock Text="{Binding Number}" />
            <Button Click="ButtonBase_OnClick" />
        </StackPanel>
    </Grid>
</Page>


결과 화면입니다.



파일

NumberTextBox.zip


반응형
댓글