数値入力、日付入力のためのユーザーコントロール(WPF) 数値入力、日付入力のためのユーザーコントロール(WPF)

以下のプログラムは、数値や日付を入力する TextBox を拡張したユーザーコントロールのサンプルプログラムです。

数値入力

                  
using System;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace UserContril
{
    /// <summary>
    /// NumericTextBox.xaml の相互作用ロジック
    /// <summary>
    public partial class NumericTextBox : TextBox
    {
        public NumericTextBox()
        {
            InitializeComponent();
            this.Loaded += OnLoaded;
            this.PreviewTextInput += TextBox_OnPreviewTextInput;
            this.GotFocus += TextBox_GotFocus;
            this.PreviewLostKeyboardFocus += TextBox_PreviewLostKeyboardFocus;
            this.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            this.Text = "";
        }

        public int IntValue()
        {
            string txt = this.Text.Replace(",", "");
            int int_value;
            double double_value;
            if (double.TryParse(txt, out double_value))
            {
                int_value = (int)double_value;
            }
            else
            {
                int_value = 0;
            }
            return int_value;
        }

        public double DoubleValue()
        {
            string txt = this.Text.Replace(",", "");
            double double_value;
            if (!double.TryParse(txt, out double_value))
            {
                double_value = 0;
            }
            return double_value;
        }

        public Decimal DecimalValue()
        {
            string txt = this.Text.Replace(",", "");
            decimal decimal_value;
            if (!decimal.TryParse(txt, out decimal_value))
            {
                decimal_value = 0;
            }
            return decimal_value;
        }

        public void SetValue(object value)
        {
            String format = (string)this.Format;
            if (value != null)
            {
                if (value is int)
                {
                    if (format == null) format = "D";
                    this.Text = ((int)value).ToString(format);
                }
                else if (value is double)
                {
                    if (format == null) format = "F2";
                    this.Text = ((double)value).ToString(format);
                }
                else if (value is decimal)
                {
                    if (format == null) format = "F2";
                    this.Text = ((decimal)value).ToString(format);
                }
            }
            else
            {
                this.Text = "";
            }
        }

        public void SetIntValue(int int_value)
        {
            String format = (string)this.Format;
            if (format == null) format = "D";
            this.Text = ((int)int_value).ToString(format);
        }

        public void SetDoubleValue(double double_value)
        {
            String format = (string)this.Format;
            if (format == null) format = "F2";
            this.Text = ((double)double_value).ToString(format);
        }

        public void SetDecimalValue(decimal decimal_value)
        {
            String format = (string)this.Format;
            if (format == null) format = "F2";
            this.Text = ((decimal)decimal_value).ToString(format);
        }

        public String Format { set; get; }
        public bool IsNotDisplayZero { set; get; }

        private void TextBox_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            e.Handled = new Regex("[^0-9.-]+").IsMatch(e.Text);
        }

        private void TextBox_PreviewLostKeyboardFocus(object sender, RoutedEventArgs e)
        {
            var s = sender as TextBox;
            string txt = s.Text.Replace(",", "");
            int int_value;
            double double_value;
            if (Text.Length > 0)
            {
                if (double.TryParse(txt, out double_value))
                {
                    int_value = (int)double_value;
                }
                else
                {
                    e.Handled = true;
                    return;
                }
            }
            else
            {
                double_value = 0;
                int_value = 0;
                if (IsNotDisplayZero == true) return;
            }
            String sbuf2;
            String format = (string)this.Format;
            if (format == null) format = "D";
            if (Regex.IsMatch(format, "[FN][1-9]*") || format.IndexOf(".") > 0)
            {
                sbuf2 = double_value.ToString(format);
            }
            else
            {
                sbuf2 = int_value.ToString(format);
            }
            this.Text = sbuf2;
        }

        private void TextBox_GotFocus(object sender, EventArgs e)
        {
            var s = sender as TextBox;
            s.Text = s.Text.Replace(",", "");
            s.SelectAll();
        }

        private void OnMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (this.IsFocused)
            {
                return;
            }
            this.Focus();
            e.Handled = true;
        }
    }
}
                
            
*Enterが押された後(フォーカスが外れた後)の入力チェックは、Try.Parseが成功するかどうかだけで判断しています。

追加プロパティ
Format 数値編集書式を指定する(ToStringで使用できる形式)
IsNotDisplayZero 入力した値が0の時、何も表示しない(trueまたはfalse )

追加メソッド
IntValue() 内容をintで取得します
DoubleValue() 内容をdoubleで取得します
DecimalValue() 内容をdecimalで取得します
SetValue(Object) int, double, decimal型の数値を表示します
SetIntValue(int) int型の数値を表示します
SetDoubleValue(double) double型の数値を表示します
SetDecimalValue(decimal) decimal型の数値を表示します


日付入力

                  
using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace UserControl

{
    /// ;<ummary>
    /// DateTextBox.xaml の相互作用ロジック
    /// ;<ummary>
    public partial class DateTextBox : TextBox
    {
        public DateTextBox()
        {
            InitializeComponent();
            this.Loaded += OnLoaded;
            this.PreviewTextInput += TextBox_OnPreviewTextInput;
            this.GotFocus += TextBox_GotFocus;
            this.PreviewLostKeyboardFocus += TextBox_PreviewLostKeyboardFocus;
            this.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            this.Text = "";
        }

        public DateTime? Date()
        {
            string txt = this.Text;
            if (txt.Length > 0)
            {
                DateTime inDay;
                DateTime.TryParse(txt, out inDay);
                return inDay;
            }
            else
            {
                return null;
            }
        }

        public void SetDate(object date)
        {
            if (date != null)
            {
                if (date is DateTime)
                {
                    this.Text = ((DateTime)date).ToString("yyyy年MM月dd日");
                }
                else
                {
                    this.Text = "";
                }
            }
            else
            {
                this.Text = "";
            }
        }

        public String Format { set; get; }
        public bool Default { set; get; }

        private void TextBox_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
        {
            e.Handled = new Regex("[^0-9.-/]+").IsMatch(e.Text);
        }

        private void TextBox_PreviewLostKeyboardFocus(object sender, RoutedEventArgs e)
        {
            var s = sender as TextBox;
            string txt = s.Text.Replace(".", "/");
            DateTime today = DateTime.Today;
            DateTime inDay;
            DateTime testDay;
            String dt;
            if (txt.Length == 0)
            {
                if (Default == false)
                {
                    return;
                }
                this.Text = today.ToString("yyyy年MM月dd日");
            }
            if (txt.Where(c => c == '/').Count() == 0)
            {
                dt = today.Year + "/" + today.Month + "/" + txt;
                if (DateTime.TryParse(dt, out inDay))
                {
                    this.Text = inDay.ToString("yyyy年MM月dd日");
                }
            }
            if (txt.Where(c => c == '/').Count() == 1)
            {
                dt = today.Year + "/" + txt;
                if (DateTime.TryParse(dt, out inDay))
                {
                    this.Text = inDay.ToString("yyyy年MM月dd日");
                }
            }
            if (txt.Where(c => c == '/').Count() == 2)
            {
                if (DateTime.TryParse(txt, out inDay))
                {
                    this.Text = inDay.ToString("yyyy年MM月dd日");
                }
            }
            if (DateTime.TryParse(this.Text, out testDay)) return;
            e.Handled = true;
        }

        private void TextBox_GotFocus(object sender, EventArgs e)
        {
            var s = sender as TextBox;
            s.SelectAll();
        }

        private void OnMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (this.IsFocused)
            {
                return;
            }
            this.Focus();
            e.Handled = true;
        }
    }
}
                
            
*Enterが押された後(フォーカスが外れた後)の入力チェックは、Try.Parseが成功するかどうかだけで判断しています。

追加プロパティ
Format 日付編集フォーマットを指定する
指定しない場合は”yyyy年mm月dd日”になる
Default 何も入力しない場合に、システム日付を表示するか指定する(trueまたはfalse )

追加メソッド
Date() 内容をdateで取得します。
何も入力されていない時は”null”が帰ります。
SetDate(date) date型の日付を表示します


xaml内で記述する内容

                  
        <local:NumericTextBox x:Name="numeric_1" HorizontalAlignment="Left" Height="23" Margin="96,34,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="100" Format="#,0">
        <local:NumericTextBox.InputBindings>
            <KeyBinding Key="Enter" Command="{x:Static local:MyWindow.NumericIn_1}" />
        </local:NumericTextBox.InputBindings>
        </local:NumericTextBox>
        <local:DateTextBox x:Name="date_1" HorizontalAlignment="Left" Height="23" Margin="96,65,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120" Default="True">
        <local:DateTextBox.InputBindings>
            <KeyBinding Key="Enter" Command="{x:Static local:MyWindow.DateIn_1}" />
        </local:DateTextBox.InputBindings>
        </local:DateTextBox>

                
            

windowのC#で使用する

                
        public MyWindow()
        {
            InitializeComponent();
            // ウィンドウにコマンドを追加します
            CommandBindings.Add(new CommandBinding(NumericIn_1, NumericIn_1Exec));
            CommandBindings.Add(new CommandBinding(DateIn_1, DateIn_1Exec));
        }

        // コマンドを定義してインスタンス化する
        public static RoutedCommand NumericIn_1 = new RoutedCommand();
        public static RoutedCommand DateIn_1 = new RoutedCommand();

        // numeric_1でEnterキーが押されると、実行される
        private void NumericIn_1Exec(object sender, ExecutedRoutedEventArgs e)
        {
            /* ここに入力後の処理を書く */
        }

        // date_1でEnterキーが押されると、実行される
        private void DateIn_1Exec(object sender, ExecutedRoutedEventArgs e)
        {
            /* ここに入力後の処理を書く */
        }