Here's my working example, which bind correctly the ViewModel and trigger correctly StringFormat
and ValidateMaskDecimal
:
<ListBox x:Name="Difetti"
ItemsSource="{Binding Difetti}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBox x:Name="Metro"
controls:TextBoxHelper.Watermark="Metro"
PreviewTextInput="ValidateMaskDecimal">
<TextBox.Text>
<Binding Path="Metro"
StringFormat="{}{0:0.0##########}">
</Binding>
</TextBox.Text>
</TextBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Now, if I try to do somethings similar on code behind (removing ListBox, and bind a unique TextBox
to the data model at some specific index = 0
):
<TextBox x:Name="Metro"
controls:TextBoxHelper.Watermark="Metro"
PreviewTextInput="ValidateMaskDecimal" />
var data = DataContext as ViewModelData;
if (data != null && data.Difetti.Count > 0) {
int difettoIndex = 0;
Metro.SetBinding(TextBox.TextProperty, new Binding
{
Source = data,
Path = new PropertyPath($"Difetti[{difettoIndex}].Metro"),
StringFormat = "{}{0:0.0##########}"
});
}
it throws a ValueStringBuilder
's ThrowFormatError
exception: System.FormatException: 'Input string was not in a correct format.'.
I don't get why. Where am I wrong? Shouldn't the code give to me the same result?
Metro on DataModel its configured this way (nullable decimal
):
private decimal? metro;
public decimal? Metro
{
get { return metro; }
set { SetField(ref metro, value, "Metro"); }
}
{}
prefixed to the string format is specific for XAML. You don't need it in code.
Of course, you can check the string format text created in XAML.
BindingExpression expression = BindingOperations.GetBindingExpression(Metro, TextBox.TextProperty);
string format = expression.ParentBinding.StringFormat;
Debug.WriteLine(format);