2

I have the need to write part of the text inside a button with a different foreground. Until now, following this solution, i was using the following piece of code:

<Button>
  <TextBlock Margin="20"
           FontSize="24"
           FontStyle="Normal"
           FontWeight="Medium"
           Foreground="#FF1384F5">
       <Run>text1</Run>
       <Run Foreground="#FF1372D3" Text="{Binding MyBinding}"/>
       <Run >text2</Run>
   </TextBlock>
</Button>

now i have the need to change the whole text based on a trigger, so i builded a DataTriger like the following:

<TextBlock.Style>
     <Style TargetType="{x:Type TextBlock}">
         <Style.Triggers>
             <DataTrigger Binding="{Binding MyBoolean}" Value="True">
                 <Setter Property="Text">
                      <Setter.Value>
                           <Run>text1</Run>
                           <Run Foreground="#FF1372D3" Text="{Binding MyBinding}"/>
                           <Run >text2</Run>
                      </Setter.Value>
                  </Setter>
              </DataTrigger>
             <DataTrigger Binding="{Binding MyBoolean}" Value="False">
                 <Setter Property="Text" Value="text3" />
              </DataTrigger>
          </Style.Triggers>
      </Style>
</TextBlock.Style>

of course this doesn't work because the property value is setted more than once. Looking for a solution i found this . It basically says to use multi binding

<Setter.Value>
    <MultiBinding StringFormat="{}{0}{1}{2}"><!-- Format as you wish -->
        <Binding Path="SelectedItem.iso"/>
        <Binding Source="{x:Static System:Environment.NewLine}"/>
        <Binding Path="SelectedItem.value"/>
    </MultiBinding>
</Setter.Value>

But i'm not sure if it fit my situation, and how to use it eventually.

Rekshino
  • 6,954
  • 2
  • 19
  • 44
Daniele Sartori
  • 1,674
  • 22
  • 38

1 Answers1

2

Runs will be set to the TextBlock.Inlines property, which has only getter, no setter. So you can't set Runs in the Style.

You can use two TextBlock elements and bind MyBoolean to the Visibility property of them:

<Grid>
    <Grid.Resources>
        <local:BoolToVisConverter x:Key="btoviscnv"/>
    </Grid.Resources>
    <TextBlock Text="text3" Visibility="{Binding MyBoolean, Converter={StaticResource btoviscnv}, ConverterParameter='not'}"/>
    <TextBlock Visibility="{Binding MyBoolean, Converter={StaticResource btoviscnv}}">
        <Run>text1</Run>
        <Run Foreground="#FF1372D3" Text="{Binding MyBinding}"/>
        <Run>text2</Run>
    </TextBlock>
</Grid>

public class BoolToVisConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var bvalue = (bool)value;
        if ((parameter as string)?.Equals("not") ?? false)
        {
            bvalue = !bvalue;
        }
        return bvalue ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException("It's one way converter");
    }
}
Rekshino
  • 6,954
  • 2
  • 19
  • 44