دسته بندی ها
16:30 1400/04/31

جدا کردن 3رقم 3 رقم اعداد در TextBox در WPF با کدهای xaml

مشخصات سوال کننده :
کاربر : mojtabahakimian     امتیاز کاربر : 155     رتبه کاربر : 10
دسته بندی : سی شارپ WPF

به این سوال امتیاز بدهید    2
تعداد بازدید این سوال : 4128
1 نظر
fateme : سوال خیلی خوبیه. من علاقمند هستم پاسخش رو بدونم !

امتیاز کاربر : 1635   رتبه کاربر : 2   تاریخ ثبت : 02:11 1400/05/01
هوش مصنوعی

پاسخ هوش مصنوعی

برای جداسازی اعداد در یک TextBox در WPF با فرمت 3 رقم 3 رقم، می توانید از یک تبدیل کننده (Value Converter) استفاده کنید. این روش به شما این امکان را می دهد که فرمت نمایش اعداد را بدون نیاز به نوشتن کد در پشت صحنه، انجام دهید.

در ادامه مثالی از نحوه ایجاد یک Value Converter برای این کار ارایه می شود:


public class NumberFormatConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is null || !double.TryParse(value.ToString(), out double number))
        {
            return string.Empty;
        }
        return string.Format(culture, "{0:N0}", number);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is string strValue && double.TryParse(strValue, NumberStyles.AllowThousands, culture, out double number))
        {
            return number;
        }
        return 0;
    }
}

سپس این تبدیل کننده را باید به XAML خود اضافه کنید. شما می توانید آن را به منابع XAML خود اضافه کنید:



    

سپس می توانید از این تبدیل کننده در TextBox خود استفاده کنید:



این کد به شما کمک می کند تا عددی که کاربر وارد می کند به فرمت 3 رقم 3 رقم نمایش داده شود. همچنین برای تبدیل مجدد اعداد به عدد صحیح، قسمت `ConvertBack` کمک خواهد کرد.

اگر از MaskedTextBox استفاده می کنید، می توانید از قابلیت های آن برای ایجاد یک Mask مناسب استفاده کنید، اما معمولا برای جداسازی اعداد باید از Value Converter استفاده کنید.

به این پاسخ امتیاز بدهید    0
امتیاز: - رتبه: -
پاسخ دهنده : Sowgandi 21:24 1400/05/01

سلام دوست گرامی

در مورد سوالتون باید بگم اینکه شما زمانی میتونید به تکست باکس خودتون این قابلیت رو بدید که مقدار این تکست باکس رو به یک Property از نوع غیر رشته بایند کنید. و چون شما می خواهید زمانی که کاربر توی تکست باکس تایپ می کنه این اعداد جدا بشه و چون مقدار Text تکست باکس از نوع رشته هست نه از نوع double یا int به همین خاطر دیگه FormatString تکست باکس از کار میفته و به همین دلیله که کد شما کار نمیکنه. 

راه حل چیست؟

شما یا باید از کامپوننت خاصی استفاده کنید این کار رو انجام بده. برخی از ابزارهای تکست باکس وجود داره که این کار رو انجام میده، فقط کافیه یه سرج تو اینترنت بزنید و کامپوننت تکست باکس ها مخصوص این کار رو پیدا کنید. (من خودم چون در این مورد از کامپوننت استفاده نمی کنم موردی رو هم نمی شناسم که معرفی کنم)

راه حل دوم استفاده از یک کلاس هست که تکست باکس مورد نظرتون رو به قابلیت جداکننده اعداد تبدیل میکنه!! 

در این روش که روش ابداعی خودم هست یک کلاس در بدنه نرم افزار شما قرار میگیره و شما هر تکست باکسی که میخواهید از نوع جدا کننده باشه به اول نام اون Num (مخفف Number) رو اضافه می کنید. کار این کلاس اینه که تمام تکست باکس هایی که در پروژه شما، نام اونها با این سه حرف شروع بشه رو شناسایی می کنه و برای اونها یک Code Behind مخصوص خودش رو می سازه و بدون اینکه شما حتی یک خط کد اضافی بنویسید تکست باکس شمارو سفارشی می کنه و format string برای اونها فعال میکنه. طوری که انگار از کامپوننت استفاده کردید! 

لازم به ذکر است که Num سه حرفی است که من خودم گذاشتم و شما میتونید به سلیقه خودتون تغییرش بدید.

برای استفاده از این روش در بدنه نرم افزار خودتون کلاس زیر رو قرار بدید.

using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Collections.Generic;

namespace CustomTexbox
{
    class TextBoxFormat
    {
        public static void FormatStringTexBox(Window win)
        {
            foreach (var item in FindVisualChildren<TextBox>(win))
            {
                if (item.Name.StartsWith("Num")) //// نماد شناسایی تکست باکس که میتونه به دلخواه شما تغییر کنه
                {
                    item.TextChanged += new TextChangedEventHandler(FormatTextBoxNumber);
                }    
            }
        }
        public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
        {
            if (depObj != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
                {
                    var child = VisualTreeHelper.GetChild(depObj, i);

                    if (child != null && child is T)
                        yield return (T)child;

                    foreach (T childOfChild in FindVisualChildren<T>(child))
                        yield return childOfChild;
                }
            }
        }
        public static void FormatTextBoxNumber(object sender, RoutedEventArgs e)
        {
            try
            {
                //////////////////جدا کردن سه رقم اعداد 
                var text = ((TextBox)sender);
                if (text.Text.Length == 0) { return; }
                double range;
                if (!Double.TryParse(text.Text, out range))
                {
                    text.Text = text.Text.Replace(text.Text.Substring(text.Text.Length - 1, 1), "");
                }

                if (text.Text != string.Empty)
                {
                    if (text.Text.Substring(text.Text.Length - 1, 1) == ".") { return; }
                    text.Text = string.Format("{0:#,##0.####}", double.Parse(text.Text.Trim()));
                    text.Select(text.MaxLength, 0);
                }
                ////////////////////////////////////////               
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}

من نام این کلاس رو CustomTexbox گذاشتم ولی شما هر نام دیگه که دوست دارید میتونید بذارید.

حالا فقط کافیه که به اول نام تکست باکس خود Num رو اضافه کنید. مانند نمونه زیر:

 <TextBox x:Name="Num_Textbox1" Text="" MaxLength="25" />

خاصیت MaxLength رو هم برای تکست باکس فعال کنید. عددش مهم نیست فقط فعال باشه (من روی 25 گذاشتم)

فقط باید ویندو یا فرمی که میخواهید باهاش کار کنید رو فعال کنید تا کلاس ما بتونه اون رو بشناسه. برای این کار توی رویداد لود فرم خودتون کد زیر رو هم بنویسید و تمام...

TextBoxFormat.FormatStringTexBox(this);

حالا دیگه توی فرم خودتون به هر تعداد تکس باکس که دوست دارید میتونید قرار بدید و بدون نوشتن حتی یک خط Code behinde تکست باکس مخصوص اعداد داشته باشید.

دوستان خوبم این روش رو من خودم طراحی کردم و اگر کسی از دوستان نظر یا پیشنهادی برای بهتر کردن این روش داره خوشحال میشم که مطرح کنه.

ویرایش شده در دوشنبه 4 مرداد 1400 ساعت 03:09:12
به این پاسخ امتیاز بدهید    7
امتیاز: 876 رتبه: 3
4 نظر
saedbfd : تشکر بسیار پاسخ خوب و عالی بود.

امتیاز کاربر : 1664   رتبه کاربر : 1   تاریخ ثبت : 09:33 1400/05/01
fateme : عالی بود. ممنون از پاسخ. خیلی دنبال پاسخ این سوال بودم. تشکر از شما بخاطر پاسخ خوبتون.

امتیاز کاربر : 1635   رتبه کاربر : 2   تاریخ ثبت : 09:38 1400/05/01
hamid_b : عالی بود. ممنون

امتیاز کاربر : 518   رتبه کاربر : 4   تاریخ ثبت : 09:45 1400/05/01
Sowgandi : خواهش میکنم، ممنون از همه دوستان

امتیاز کاربر : 876   رتبه کاربر : 3   تاریخ ثبت : 10:25 1400/05/01
ادامه نظرات ...
پاسخ دهنده : mojtabahakimian 08:34 1400/05/03

این یکی هم با بایندینگ کردن میشه 

XAML :

<TextBox x:Name="txt1" TextWrapping="Wrap" Text="{Binding NumericValue, StringFormat={}{0:N0},UpdateSourceTrigger=PropertyChanged}"/>

Binding :  

    public partial class MainWindow : Window
    {
        public static readonly DependencyProperty NumericValueProperty = DependencyProperty.Register(
          "NumericValue",
          typeof(double),
          typeof(MainWindow),
          new PropertyMetadata(default(double), MainWindow.OnNumericValueChanged));

        public double NumericValue
        {
            get => (double)GetValue(MainWindow.NumericValueProperty);
            set => SetValue(MainWindow.NumericValueProperty, value);
        }

        // Property changed callbacck
        private static void OnNumericValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var textBox = d as TextBox;
            double newValue = (double)e.NewValue;

            // Do something with the new value that was entered by the user
        }

        public MainWindow()
        {
            InitializeComponent();

            // Set DataContext to the MainWindow itself
            this.DataContext = this;

            // We want 10000 to be displayed with thousands number groups
            // like '10.000'
            //this.NumericValue = 10000;
        }
    }

 

به این پاسخ امتیاز بدهید    2
امتیاز: 155 رتبه: 10
2 نظر
Sowgandi : من این روش رو تست کردم. باید به ازای هر تکست باکس که در فرم قرار میدید تمام این کد ها رو هم بنویسید. مثلا اگر 5 تا تکست باکس این مدلی در یک فرم داشته باشیم باید چکار کنیم؟

امتیاز کاربر : 876   رتبه کاربر : 3   تاریخ ثبت : 02:15 1400/05/03
mojtabahakimian : آره درسته مشکلش همینه , عجیبه که راه حل ساده ای نداره , WPF 3000 کلاس بیشتر از ویندوز فرم داره ولی یه همچین مشکلی داره همین راه حل شما و یا استفاده از کامپوننت های رایگان مثل MahApp و Xceed خوبه باتشکر

امتیاز کاربر : 155   رتبه کاربر : 10   تاریخ ثبت : 08:12 1400/05/03
برای ارسال پاسخ لطفا وارد حساب کاربری خود شوید.   ورود