2013-08-21 8 views
61

私はWPFプログラムを作成していますが、スタイルやテンプレートのような再現可能なメソッドを使用してTextBoxのデータをフォーマットする方法を理解しようとしています。私は多くのTextBoxes(正確には95)を持っていて、それぞれ独自の数値データにバインドされています。それぞれ独自の解像度が定義されています。たとえば、データが99.123で解像度が2の場合、99.12と表示されます。同様に、データ値99と解像度3は、99.000(99ではない)と表示する必要があります。これを行う方法はありますか?スタイル/テンプレートを使用してwpfの小数点以下の桁数をフォーマットする方法は?

編集:私は明確にすべき 、そこに私が働いている現在の画面上の95件のTextBoxがありますが、私は私のプログラムで様々な画面を通じて、すべてのテキストボックスは、小数点以下の桁数を正しく表示したいです。今私はそれについて考えている、これらのいくつかはTextBoxes(私が今作業している画面のようなもの)とDataGridsまたはListViewsですが、TextBoxesのために働く方法を理解できれば、それは他のコントロールのためにも同様です。

あり、この場合、共有するために多くのコードではないのですが、私はそれをより明確にしようとします:

私は、次のプロパティ(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 

そして私が持っているXAMLで:

<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(私の解決策): それは後に離れてFRを歩くことが判明しますコンピュータをしばらくの間、私は顔の私を見つめていた簡単な答えを見つけるために戻ってきた。ビューモデルでデータをフォーマットしてください!

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

「IValueConverter」を使用していますか?実際の値と解像度をコンバーターに渡し、それ自体の中であなたのために切り上げます。これらの 'TextBox'がどれだけ正確に生成されているかを知らなくても、' StringFormat'を提案するのは難しいです。 – Viv

+0

現在のコードとXAMLをポストします。そうでなければ、それはすべての推測であり、役に立たない推測です。 –

+0

質問にもっと情報を追加しましたが、それはうまくいけば分かります。 – AXG1010

答えて

124

あなたはBindingStringFormatを使用する必要があります。あなたはstandard string formats、またはcustom string formatsのいずれかを使用することができます。

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

注意targetプロパティはString型であるときStringFormatにのみ動作すること。 Contentプロパティ(typeof(object))を設定する場合は、カスタムStringFormatConverterlike here)を使用し、フォーマット文字列をConverterParameterとして渡す必要があります。

ので、更新のための質問

編集、あなたのViewModelは精度が定義されている場合、私はMultiBindingとしてこれをやって、そしてあなた自身のIMultiValueConverterの作成をお勧めしたいです。これは実際には簡単なバインドからMultiBindingに展開する必要があるものにはかなり面倒ですが、コンパイル時に精度がわからない場合は、これでほとんどすべてのことができます。あなたのIMultiValueConverterは、値と精度を取り、フォーマットされた文字列を出力する必要があります。 String.Formatを使用してこれを行うことができます。

しかし、ContentControlのようなもののために、あなたははるかに容易Styleでこれを行うことができます。

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

ContentStringFormatを公開する任意のコントロールは次のように使用することができます。残念ながら、TextBoxにはそのようなものはありません。

+0

情報ありがとうございました。 – AXG1010

+1

StringFormatが '#、#。00 'に設定された例はコンパイルされません。コンマは' Binding'マークアップ拡張の属性の区切り文字として解釈されます。 – Gigi

+0

@Gigi、そうですが、簡単に使うことができます: 'StringFormat = {} {0:#、#。00}'。答えを正しく更新するように更新します。 –

0
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; 
     } 
    } 
+4

いくつかの説明は、あなたの答えの質を大幅に向上させるでしょう。 – mrun

1

0.299のような入力を与えた場合、整数の場所に0が表示されません。それはWPF UIで.3を示します。ですから、私は次の文字列形式を使用することを提案しました。

<TextBox Text="{Binding Value, StringFormat={}{0:#,0.0}}" 
関連する問題