Reputation: 4185
I have a ListView
with a column that shows the state two letter appreviation.
Based on the value of a Boolean property (HasWorkState
) I would like to add parenthesis around the state abbreviation when HasWorkState = false
.
For instance:
HasWorkState = true
display OH
HasWorkState = false
display (OH)
The state abbreviation is displayed in a GridViewColumn
:
<!-- Work State -->
<GridViewColumn Width="{Binding ActualWidth,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Grid}},
Converter={StaticResource MathConverter}, ConverterParameter=(x/10)*0.5}">
<GridViewColumn.Header>
<GridViewColumnHeader Content=" State"
HorizontalContentAlignment="Left" />
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding WorkState}"
Style="{StaticResource StateStyle}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
To this GridViewColumn
I have applied this style:
<!-- Highlight missing work states -->
<Style x:Key="StateStyle" TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding HasWorkState}" Value="False">
<Setter Property="Text" Value="{Binding StringFormat=({0})}" />
<Setter Property="ToolTip" Value="Work location unspecified. Using residence state." />
</DataTrigger>
</Style.Triggers>
</Style>
I know this style is being applied correctly as the ToolTip
is being displayed when HasWorkState = false
. I just need to know how to add the parenthesis. What I currently have for the Text
value setter is not working.
Upvotes: 0
Views: 1533
Reputation: 37059
You've got a solution, but it's worth knowing why you had the problem: Because you're setting Text
with an attribute on the TextBlock element, the style can't override that. If you used a style setter to apply the default {Binding WorkState}
, the style would be able to override it.
I prefer to keep things like this in the view, so my approach would be this:
<ContentControl Content="{Binding WorkState}" Style="{StaticResource StateStyle}" />
State style:
<Style x:Key="StateStyle" TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding HasWorkState}" Value="False">
<!-- Leave the content alone and just change the format string -->
<Setter Property="ContentStringFormat" Value="({0})" />
<Setter
Property="ToolTip"
Value="Work location unspecified. Using residence state."
/>
</DataTrigger>
</Style.Triggers>
</Style>
Upvotes: 2
Reputation: 1729
The best way is to add that property to your view model. Something like this in your view model:
internal class StateStyleViewModel : INotifyPropertyChanged
{
private bool hasWorkState;
private string workState;
public event PropertyChangedEventHandler PropertyChanged;
private string WorkState
{
get { return workState; }
set
{
if (value == workState) return;
workState = value;
OnPropertyChanged();
//Notify that the value of the dependent property has changed.
OnPropertyChanged(nameof(DisplayWorkState));
}
}
public bool HasWorkState
{
get { return hasWorkState; }
set
{
if (value == hasWorkState) return;
hasWorkState = value;
OnPropertyChanged();
//Notify that the value of the dependent property has changed.
OnPropertyChanged(nameof(DisplayWorkState));
}
}
/// <summary>
/// Property for binding
/// </summary>
public string DisplayWorkState => HasWorkState ? WorkState : $"({WorkState})";
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Then you just bind to DisplayWorkState instead of WorkState
Upvotes: 1