Reputation: 585
I have been trying to implement a simple value converter I just can't figure out why the StringFormat is not being applied. The positive values turn green and the negatives red but instead of getting the desired result (+15.74), I end up with: 15.74747474.
How can I get this to work? Can someone please give me an idea of what I need to change?
XAML
<Window.Resources>
<local:PositiveConverter x:Key="PositiveConverter"/>
<Style TargetType="TextBlock" x:Key="NumericTextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Text, RelativeSource={RelativeSource Self}, Converter={StaticResource PositiveConverter}}" Value="True">
<Setter Property="Foreground" Value="Green"/>
<Setter Property="Text" Value="{Binding StringFormat='({0:+0.0})'}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Text, RelativeSource={RelativeSource Self}, Converter={StaticResource PositiveConverter}}" Value="False">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Text" Value="{Binding StringFormat='({0:-0.0})'}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<TextBlock Text="{Binding ActualValue}" Style="{StaticResource NumericTextBlock}"/>
</StackPanel>
</Grid>
ViewModel
namespace My.ViewModel
{
public class LocationViewModel : UserControl, INotifyPropertyChanged
{
public MyViewModel()
{
SetActualValue();
}
public DateTime mDate = DateTime.Now;
public DateTime MDate
{
get { return mDate; }
set
{
if (value == mDate)
{
return;
}
else
{
mDate = value;
OnPropertyChanged("MDate");
SetActualValue();
}
}
}
double _actualValue;
public double ActualValue
{
get { return _actualValue; }
set
{
_actualValue = value;
OnPropertyChanged("ActualValue");
}
}
ValueConverter
public class PositiveConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var number = 0.0;
var isNumber = double.TryParse(value.ToString(), out number);
return isNumber && number >= 0.0;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Upvotes: 1
Views: 532
Reputation: 128061
Setting
Text="{Binding ActualValue}"
directly on the TextBlock has higher value precedence than a Style Setter like
<Setter Property="Text" Value="{Binding StringFormat='({0:+0.0})'}"/>
So the Bindings from the Setter will never be applied. They are also wrongly written, because they miss the property path ActualValue
.
Your approach won't work. You should instead have DataTriggers with Bindings to the view model property like this:
<Style TargetType="TextBlock" x:Key="NumericTextBlock">
<Setter Property="Text"
Value="{Binding ActualValue, StringFormat='({0:+0.0})'}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ActualValue, Converter={StaticResource PositiveConverter}}"
Value="True">
<Setter Property="Foreground" Value="Green"/>
<Setter Property="Text"
Value="{Binding ActualValue, StringFormat='({0:+0.0})'}"/>
</DataTrigger>
<DataTrigger Binding="{Binding ActualValue, Converter={StaticResource PositiveConverter}}"
Value="False">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="Text"
Value="{Binding ActualValue, StringFormat='({0:-0.0})'}"/>
</DataTrigger>
</Style.Triggers>
</Style>
and remove Text="{Binding ActualValue}"
from the TextBlock.
Upvotes: 3