Stil / şablon kullanarak wpf'deki ondalık basamak sayısını nasıl biçimlendirebilirim?


94

Bir WPF programı yazıyorum ve bir TextBox'taki verileri bir stil veya şablon gibi tekrarlanabilir bir yöntemle biçimlendirmenin bir yolunu bulmaya çalışıyorum. Çok sayıda TextBox'ım var (tam olarak 95) ve her biri kendi çözünürlüğünü tanımlayabilen kendi sayısal verilerine bağlı. Örneğin, veri 99.123 ve 2 çözünürlüklü ise 99.12. Benzer şekilde 99 veri değeri ve çözünürlük 3 99.000 (99 değil) olarak görüntülenmelidir. Bunu yapmanın bir yolu var mı?

Düzenleme: Açıklığa kavuşturmalıyım, üzerinde çalıştığım ekranda 95 Metin Kutusu var, ancak programımdaki çeşitli ekranlardaki her Metin Kutusunun doğru ondalık basamak sayısını göstermesini istiyorum. Şimdi düşünüyorum da, bunlardan bazıları TextBoxes (şu anda çalıştığım ekran gibi) ve bazıları DataGrids veya ListViews, ancak TextBoxes için nasıl çalıştırılacağını bulabilirsem, eminim anlayabilirim diğer kontroller için de çıktı.

Bu durumda paylaşılacak çok fazla kod yok, ancak daha net hale getirmeye çalışacağım:

Aşağıdaki özellikleri içeren bir Görünüm Modelim var (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

ve XAML'de var:

<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}" />

DÜZENLEME2 (benim çözümüm): Bir süre bilgisayardan uzaklaştıktan sonra, yüzüme bakan basit bir cevap bulmak için geri döndüğüm ortaya çıktı. Görünüm modelindeki verileri biçimlendirin!

    Public ReadOnly Property Value As String
        Get
            Return (Strings.FormatNumber(Math.Round(_signal.DisplayValue, _signal.DisplayResolution), _signal.DisplayResolution))
        End Get
    End Property

1
bir IValueConverter? Gerçek değeri ve çözünürlüğü dönüştürücüye aktarın ve sizin için yuvarlamayı kendi içinde yapmasına izin verin. Bu StringFormat95'lerin tam olarak nasıl TextBoxüretildiğini bilmeden bir önermek zor .
Viv

Geçerli kodu ve XAML'yi gönderin. Aksi takdirde hepsi spekülasyonlar ve yararsız tahminlerdir.
Federico Berasategui

Soruya daha açık hale getirmesi gereken bazı bilgiler ekledim.
AXG1010

Yanıtlar:


197

Sen kullanmalıdır StringFormatüzerinde Binding. Ya kullanabilirsiniz standart dize biçimlerini veya özel dize biçimlerini :

<TextBox Text="{Binding Value, StringFormat=N2}" />
<TextBox Text="{Binding Value, StringFormat={}{0:#,#.00}}" />

StringFormatYalnızca target özelliği string türünde olduğunda çalıştığını unutmayın . ContentÖzellik ( typeof(object)) gibi bir şey ayarlamaya çalışıyorsanız , bir özel StringFormatConverter( buradaki gibi ) kullanmanız ve biçim dizenizi ConverterParameter.

Güncellenen soru için düzenleyin

Yani, ViewModelhassasiyeti tanımlıyorsanız, bunu bir olarak yapmanızı MultiBindingve kendinizinkini oluşturmanızı öneririm IMultiValueConverter. Basit bir bağlamadan a'ya genişletilmesi gereken bir bağlantıya geçmek pratikte oldukça can sıkıcıdır MultiBinding, ancak derleme zamanında hassasiyet bilinmiyorsa, yapabileceğiniz tek şey budur. Sizin IMultiValueConverterdeğeri ve hassasiyet, ve çıktı biçimlendirilmiş dize almak gerekir. Bunu kullanarak yapabilirsiniz String.Format.

Ancak, a gibi şeyler için ContentControlbunu a ile çok daha kolay yapabilirsiniz Style:

<Style TargetType="{x:Type ContentControl}">
    <Setter Property="ContentStringFormat" 
            Value="{Binding Resolution, StringFormat=N{0}}" />
</Style>

A'yı ortaya çıkaran herhangi bir kontrol bu ContentStringFormatşekilde kullanılabilir. Ne yazık ki TextBoxböyle bir şey yok.


6
StringFormat değerine ayarlanmış örnek #,#.00derleme yapmaz - virgül, Bindingbiçimlendirme uzantısındaki öznitelikler için bir sınırlayıcı olarak yorumlanır .
Gigi

@Gigi, haklısın, ancak kolayca bu kadar mi kullanabilirsiniz: StringFormat={}{0:#,#.00}. Doğru çalışması için cevabı güncelleyeceğim.
Abe Heidebrecht

'StringFormat = N {0}' harika çalışıyor. 2 hassasiyeti için iki ondalık sayı gösterilmesini istiyorum, '10 .00 'dışında, bu durumda' 10 'görüntülenmesini istiyorum. Kesinliğe bağlanırken bunu yapmanın bir yolu var mı? Görünüşe göre bir dönüştürücü kullanmam gerekecek.
Gordon Slysz

NET dize biçimleri kullanılarak sunulan ondalık sayıları değiştirmenin bir yolu olduğunu sanmıyorum, bu nedenle bir dönüştürücü yazmanız daha iyi olur.
Abe Heidebrecht

Neden iki tanımlayıcı 0: #, #. 00 kullandığınızı açıklayabilir misiniz, bunlardan sadece biri yeterli olmayacak mı?
Lei Yang

7

Kabul edilen cevap 0.299 gibi girdi verirken tamsayı yerinde 0 göstermez. WPF kullanıcı arayüzünde .3 gösterir. Bu yüzden aşağıdaki dize biçimini kullanma önerim

<TextBox Text="{Binding Value,  StringFormat={}{0:#,0.0}}" 

Merhaba, çözümünüz tamam, ancak N1 (2,3 ...) anahtar kelimesini kullanmayı tercih ederim çünkü yazım hatalarını önler ve en azından nasıl görüntüleneceğinden eminsiniz. Ama aslında ikinci öneri, bahsettiğiniz gibi 0 if değeri <0 göstermiyor.
Kevin VDF

-2
    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;
        }
    }

9
Bazı açıklamalar cevabınızın kalitesini önemli ölçüde artıracaktır.
mrun
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.