Saya menulis program WPF dan saya mencoba mencari cara untuk memformat data dalam TextBox melalui beberapa metode berulang seperti gaya atau template. Saya memiliki banyak TextBox (95 tepatnya) dan masing-masing terikat pada data numeriknya sendiri yang masing-masing dapat memiliki resolusi sendiri. Misal jika datanya 99.123 dengan resolusi 2 maka seharusnya menampilkan 99.12. Demikian pula nilai data 99 dan resolusi 3 harus ditampilkan sebagai 99.000 (bukan 99). Apakah ada cara untuk melakukan ini?
Sunting: Saya harus menjelaskan, ada 95 Kotak Teks di layar saat ini yang saya kerjakan, tetapi saya ingin setiap Kotak Teks di berbagai layar dalam program saya menampilkan jumlah tempat desimal yang benar. Sekarang saya memikirkannya, beberapa di antaranya adalah TextBoxes (seperti layar yang sedang saya kerjakan sekarang) dan beberapa adalah DataGrids atau ListView, tetapi jika saya dapat mengetahui cara membuatnya berfungsi untuk TextBox, saya yakin saya bisa memahami itu untuk kontrol lainnya juga.
Tidak banyak kode untuk dibagikan dalam kasus ini, tetapi saya akan mencoba membuatnya lebih jelas:
Saya memiliki Model Tampilan yang berisi properti berikut (vb.net):
Public ReadOnly Property Resolution As Integer
Get
Return _signal.DisplayResolution
End Get
End Property
Public ReadOnly Property Value As Single
Get
Return Math.Round(_signal.DisplayValue, Resolution)
End Get
End Property
dan di XAML saya punya:
<UserControl.Resources>
<vm:SignalViewModel x:Key="Signal" SignalPath="SomeSignal"/>
</UserControl.Resources>
<TextBox Grid.Column="3" IsEnabled="False" Text="{Binding Path=Value, Source={StaticResource Signal}, Mode=OneWay}" />
EDIT2 (solusi saya): Ternyata setelah meninggalkan komputer beberapa lama, saya kembali untuk menemukan jawaban sederhana yang menatap wajah saya. Format data dalam model tampilan!
Public ReadOnly Property Value As String
Get
Return (Strings.FormatNumber(Math.Round(_signal.DisplayValue, _signal.DisplayResolution), _signal.DisplayResolution))
End Get
End Property
sumber
IValueConverter
? Berikan nilai aktual dan resolusi ke konverter dan biarkan konverter melakukan pembulatan untuk Anda di dalamnya. Sulit untuk menyarankanStringFormat
tanpa mengetahui bagaimana tepatnya 95TextBox
ini dihasilkan.Jawaban:
Anda harus menggunakan
StringFormat
diBinding
. Anda dapat menggunakan format string standar , atau format string kustom :<TextBox Text="{Binding Value, StringFormat=N2}" /> <TextBox Text="{Binding Value, StringFormat={}{0:#,#.00}}" />
Perhatikan bahwa
StringFormat
hanya bekerja jika properti target berjenis string. Jika Anda mencoba menyetel sesuatu sepertiContent
properti (typeof(object)
), Anda perlu menggunakan customStringFormatConverter
( seperti di sini ), dan meneruskan string format Anda sebagaiConverterParameter
.Edit untuk pertanyaan yang diperbarui
Jadi, jika Anda
ViewModel
mendefinisikan presisi, saya sarankan melakukan ini sebagaiMultiBinding
, dan membuatnya sendiriIMultiValueConverter
. Ini cukup menjengkelkan dalam praktiknya, untuk beralih dari pengikatan sederhana ke pengikatan yang perlu diperluas ke aMultiBinding
, tetapi jika presisi tidak diketahui pada waktu kompilasi, cukup banyak yang dapat Anda lakukan. AndaIMultiValueConverter
perlu mengambil nilainya, dan presisi, dan mengeluarkan string yang diformat. Anda dapat melakukannya dengan menggunakanString.Format
.Namun, untuk hal-hal seperti a
ContentControl
, Anda dapat lebih mudah melakukannya denganStyle
:<Style TargetType="{x:Type ContentControl}"> <Setter Property="ContentStringFormat" Value="{Binding Resolution, StringFormat=N{0}}" /> </Style>
Kontrol apa pun yang mengekspos a
ContentStringFormat
dapat digunakan seperti ini. Sayangnya,TextBox
tidak ada yang seperti itu.sumber
#,#.00
tidak dapat dikompilasi - koma diartikan sebagai pemisah untuk atribut diBinding
ekstensi markup.StringFormat={}{0:#,#.00}
. Saya akan memperbarui jawaban agar berfungsi dengan benar.Jawaban yang diterima tidak menunjukkan 0 di tempat bilangan bulat pada pemberian input seperti 0.299. Ini menunjukkan .3 di WPF UI. Jadi saran saya untuk menggunakan format string berikut
<TextBox Text="{Binding Value, StringFormat={}{0:#,0.0}}"
sumber
void NumericTextBoxInput(object sender, TextCompositionEventArgs e) { TextBox txt = (TextBox)sender; var regex = new Regex(@"^[0-9]*(?:\.[0-9]{0,1})?$"); string str = txt.Text + e.Text.ToString(); int cntPrc = 0; if (str.Contains('.')) { string[] tokens = str.Split('.'); if (tokens.Count() > 0) { string result = tokens[1]; char[] prc = result.ToCharArray(); cntPrc = prc.Count(); } } if (regex.IsMatch(e.Text) && !(e.Text == "." && ((TextBox)sender).Text.Contains(e.Text)) && (cntPrc < 3)) { e.Handled = false; } else { e.Handled = true; } }
sumber