I have a bool value that I need to display as \"Yes\" or \"No\" in a TextBlock. I am trying to do this with a StringFormat, but my StringFormat is ignored and the TextBlock
Your solution with StringFormat can't work, because it's not a valid format string.
I wrote a markup extension that would do what you want. You can use it like that :
<TextBlock Text="{my:SwitchBinding MyBoolValue, Yes, No}" />
Here the code for the markup extension :
public class SwitchBindingExtension : Binding
{
public SwitchBindingExtension()
{
Initialize();
}
public SwitchBindingExtension(string path)
: base(path)
{
Initialize();
}
public SwitchBindingExtension(string path, object valueIfTrue, object valueIfFalse)
: base(path)
{
Initialize();
this.ValueIfTrue = valueIfTrue;
this.ValueIfFalse = valueIfFalse;
}
private void Initialize()
{
this.ValueIfTrue = Binding.DoNothing;
this.ValueIfFalse = Binding.DoNothing;
this.Converter = new SwitchConverter(this);
}
[ConstructorArgument("valueIfTrue")]
public object ValueIfTrue { get; set; }
[ConstructorArgument("valueIfFalse")]
public object ValueIfFalse { get; set; }
private class SwitchConverter : IValueConverter
{
public SwitchConverter(SwitchBindingExtension switchExtension)
{
_switch = switchExtension;
}
private SwitchBindingExtension _switch;
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
try
{
bool b = System.Convert.ToBoolean(value);
return b ? _switch.ValueIfTrue : _switch.ValueIfFalse;
}
catch
{
return DependencyProperty.UnsetValue;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Binding.DoNothing;
}
#endregion
}
}
You can also use this great value converter
Then you declare in XAML something like this:
<local:BoolToStringConverter x:Key="BooleanToStringConverter" FalseValue="No" TrueValue="Yes" />
And you can use it like this:
<TextBlock Text="{Binding Path=MyBoolValue, Converter={StaticResource BooleanToStringConverter}}" />
Without converter
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Text" Value="OFF" />
<Style.Triggers>
<DataTrigger Binding="{Binding MyBoolValue}" Value="True">
<Setter Property="Text" Value="ON" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
This is a solution using a Converter
and the ConverterParameter
which allows you to easily define different strings
for different Bindings
:
public class BoolToStringConverter : IValueConverter
{
public char Separator { get; set; } = ';';
public object Convert(object value, Type targetType, object parameter,
CultureInfo culture)
{
var strings = ((string)parameter).Split(Separator);
var trueString = strings[0];
var falseString = strings[1];
var boolValue = (bool)value;
if (boolValue == true)
{
return trueString;
}
else
{
return falseString;
}
}
public object ConvertBack(object value, Type targetType, object parameter,
CultureInfo culture)
{
var strings = ((string)parameter).Split(Separator);
var trueString = strings[0];
var falseString = strings[1];
var stringValue = (string)value;
if (stringValue == trueString)
{
return true;
}
else
{
return false;
}
}
}
Define the Converter like this:
<local:BoolToStringConverter x:Key="BoolToStringConverter" />
And use it like this:
<TextBlock Text="{Binding MyBoolValue, Converter={StaticResource BoolToStringConverter},
ConverterParameter='Yes;No'}" />
If you need a different separator than ;
(for example .
), define the Converter like this instead:
<local:BoolToStringConverter x:Key="BoolToStringConverter" Separator="." />
This is another alternative simplified converter with "hard-coded" Yes/No values
[ValueConversion(typeof (bool), typeof (bool))]
public class YesNoBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var boolValue = value is bool && (bool) value;
return boolValue ? "Yes" : "No";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value != null && value.ToString() == "Yes";
}
}
XAML Usage
<DataGridTextColumn Header="Is Listed?" Binding="{Binding Path=IsListed, Mode=TwoWay, Converter={StaticResource YesNoBoolConverter}}" Width="110" IsReadOnly="True" TextElement.FontSize="12" />
The following worked for me inside a datagridtextcolumn: I added another property to my class that returned a string depending on the value of MyBool. Note that in my case the datagrid was bound to a CollectionViewSource of MyClass objects.
C#:
public class MyClass
{
public bool MyBool {get; set;}
public string BoolString
{
get { return MyBool == true ? "Yes" : "No"; }
}
}
XAML:
<DataGridTextColumn Header="Status" Binding="{Binding BoolString}">