Search code examples
wpfxamldata-bindingviewmodelrichtext

How do I get different colors for parts of string object property binded to label in ItemControl?


This is my object type:

public class selectedLevel
{
   public string Level
    {
        get;
        set;
    }

   public string PlanetSelected
    {
        get; set;

    }
   public string houseDetails
    {
        get;
        set;
    }

    
}

This is my itemTemplate:


<ItemsControl x:Name="LevelDetails" Margin="-464,416,120,-484"   BorderBrush ="Black"  ItemsSource="{Binding selectedLevels}" Grid.ColumnSpan="3" HorizontalContentAlignment="Stretch">
   <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
         <StackPanel Orientation="Horizontal"/>
      </ItemsPanelTemplate>
   </ItemsControl.ItemsPanel>
   <ItemsControl.ItemTemplate>
      <DataTemplate>
         <Grid>
            <Grid.ColumnDefinitions>
               <ColumnDefinition SharedSizeGroup="Col1" />
               <ColumnDefinition SharedSizeGroup="Col2" />
               <ColumnDefinition SharedSizeGroup="Col3" />
               <ColumnDefinition SharedSizeGroup="Col4" />
               <ColumnDefinition SharedSizeGroup="Col5" />
               <ColumnDefinition SharedSizeGroup="Col6" />
               <ColumnDefinition SharedSizeGroup="Col7" />
               <ColumnDefinition SharedSizeGroup="Col8" />
               <ColumnDefinition SharedSizeGroup="Col9" />
               <ColumnDefinition SharedSizeGroup="Col10"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
               <RowDefinition SharedSizeGroup="Row1"/>
               <RowDefinition SharedSizeGroup="Row2"/>
               <RowDefinition SharedSizeGroup="Row3"/>
            </Grid.RowDefinitions>
            <Label x:Name="LevelName" Grid.Row="0"  Content="{Binding Level}" HorizontalContentAlignment="Center" FontWeight="Bold" FontSize="16" BorderBrush="Black" BorderThickness="1" Background="{x:Null}"/>
            <Label x:Name="PlanetName" Grid.Row="1" Content="{Binding PlanetSelected}" FontSize="14" Foreground="Red" BorderBrush="Black" FontWeight="Bold" HorizontalContentAlignment="Center" BorderThickness="1" />
            <Label x:Name="LevelDetails" Grid.Row="2" HorizontalContentAlignment="Center" Content="{Binding houseDetails}" FontSize="14" BorderBrush="Black" FontWeight="Bold" BorderThickness="1" />
         </Grid>
      </DataTemplate>
   </ItemsControl.ItemTemplate>
</ItemsControl>

The User control is bound with an object with an observable collection of type selectedLevel(shown at the top).

I am adding the properties of SelectedLevels in a view model as follows:

selectedLevels.Add(new selectedLevel
{
    Level = "Mahadasha",
    PlanetSelected = Mahadashas[0].rulerName,
    houseDetails =  indicesList[0]  +  ", " + indicesList[1] + ", " + indicesList[2]
                    
});
       

I am trying to get different colors for indicesList[0], indicesList[1] and indicesList[2] in 3rd label which is bound with houseDetails but I can only change full text color and not a part of it.

I am totally lost here. Can I get some assistance on how to set different colors to parts of string?


Solution

  • It's simple, first you need to separate the houseDetails property into 3 strings, something similar to this:

    public class selectedLevel
    {
       public string Level { get; set; }
    
       public string PlanetSelected { get; set; }
    
       public string houseDetails1 { get; set; }
       public string houseDetails2 { get; set; }
       public string houseDetails3 { get; set; }
    }
    

    Then you can use a TextBlock wrapped by a Border instead of the third Label and use Runs inside it to pick a different color for each one and bind them to the corresponding properties:

    <Border HorizontalAlignment="Center" BorderBrush="Black" BorderThickness="1">
        <TextBlock x:Name="LevelDetails" Grid.Row="2" FontSize="14" FontWeight="Bold">
            <Run Text="{Binding houseDetails1}" Foreground="Red"/>,
            <Run Text="{Binding houseDetails2}" Foreground="Green"/>,
            <Run Text="{Binding houseDetails3}" Foreground="Blue"/>
        </TextBlock>
    </Border>
    
    

    And then in the view model:

    selectedLevels.Add(new selectedLevel
    {
        Level = "Mahadasha",
        PlanetSelected = Mahadashas[0].rulerName,
        houseDetails1 =  indicesList[0],
        houseDetails2 =  indicesList[1],
        houseDetails3 =  indicesList[2]                   
    });