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

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

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

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

امتیاز کاربر : 1617   رتبه کاربر : 2   تاریخ ثبت : 02:11 1400/05/01
پاسخ دهنده : 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
امتیاز: 871 رتبه: 3
4 نظر
saedbfd : تشکر بسیار پاسخ خوب و عالی بود.

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

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

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

امتیاز کاربر : 871   رتبه کاربر : 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 تا تکست باکس این مدلی در یک فرم داشته باشیم باید چکار کنیم؟

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

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