Search code examples
c#wpftextblock

Coloring some of the characters


I have a textblock inside a list view in which I want to back color some of the characters dynamically or by some way binding the back color of a different text block.

Since there is some logic of how a character is colored, how can I do that?

Attaching my XAML:

<ListView x:Name="LV" ItemsSource= "{Binding  Lggv}" SelectionChanged="dataGridData_SelectionChanged" ItemContainerStyle="{StaticResource ListViewItemStyle}" >
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <Border BorderThickness="1" BorderBrush="Black">
                    <Border.Visibility>
                        <MultiBinding Converter="{StaticResource V_converter }">
                            <Binding Path="Type"></Binding>
                            <Binding Path="NodeID"></Binding>
                            <Binding Path="TLV"></Binding>
                        </MultiBinding>
                    </Border.Visibility>
                    <Grid>
                        <Grid.Visibility>
                            <MultiBinding Converter="{StaticResource V_converter }">
                                <Binding Path="Type"></Binding>
                                <Binding Path="NodeID"></Binding>
                                <Binding Path="TLV"></Binding>
                            </MultiBinding>
                        </Grid.Visibility>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="150"></ColumnDefinition>
                            <ColumnDefinition Width="55"></ColumnDefinition>
                            <ColumnDefinition Width="1*"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <TextBlock x:Name="tbHeader" Text="{Binding Info }" AllowDrop="True"   FontWeight="Bold" Grid.Column="2" Visibility="{Binding Visibility_Header}" >

                            <TextBlock.Style>
                                <Style TargetType="TextBlock">
                                    <Setter Property="Background">
                                        <Setter.Value>
                                            <!-- this is the default background-->
                                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                                <GradientStop Color="#FFCEE6C6" Offset="0.008"/>
                                                <GradientStop Color="#FF9ECF8C" Offset="0.987"/>
                                            </LinearGradientBrush>
                                        </Setter.Value>
                                    </Setter>
                                </Style>
                            </TextBlock.Style>
                        </TextBlock>
                    </Grid>
                </Border>

                <Grid x:Name="GridData">

                    <Grid.Visibility>
                        <MultiBinding Converter="{StaticResource V_converter }">
                            <Binding Path="Type"></Binding>
                            <Binding Path="NodeID"></Binding>
                            <Binding Path="TLV"></Binding>
                        </MultiBinding>
                    </Grid.Visibility>
                    <Grid.Background>
                        <MultiBinding Converter="{StaticResource converter }">
                            <Binding Path="Type"></Binding>
                            <Binding Path="NodeID"></Binding>
                            <Binding Path="TLV"></Binding>
                        </MultiBinding>
                    </Grid.Background>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="150"></ColumnDefinition>
                        <ColumnDefinition Width="55"></ColumnDefinition>
                        <ColumnDefinition Width="1*"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Border Grid.Column="0" BorderThickness="1" BorderBrush="Black">
                        <TextBlock Text="{Binding DateTime}"  ></TextBlock>
                    </Border>
                    <Border Grid.Column="1" BorderThickness="1" BorderBrush="Black">
                        <TextBlock Text="{Binding ComPort}"></TextBlock>
                    </Border>
                    <Border Grid.Column="2" BorderThickness="1" BorderBrush="Black">
                        <TextBlock Text="{Binding Data}" ></TextBlock>
                    </Border>
                </Grid>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Solution

  • WPF makes it extremely hard to do stuff like that programmatically because WPF is built around the MVVM pattern. Therefore, to play nicely with it, you need to create a ViewModel (VM from MVVM). Here is an example ViewModel:

    // if you want runtime changes to be reflected in the UI
    public class ItemVM : INotifyPropertyChanged 
    {
        public string Text { // raise property change in setter }
        public Color BackgroundColor { // whatever you need }
    }
    

    Then create a list of ItemVM like this:

    public IEnumerable<ItemVM> Items { get; set; }
    

    Then in your XAML bind to the list and the BackgroundColor property like this:

    <ListView x:Name="MyListView" ItemsSource="{Binding Items}" HorizontalContentAlignment="Stretch">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Text}">
                <TextBlock.Background>
                    <SolidColorBrush Color="{Binding BackgroundColor}"/>
                </TextBlock.Background>
                </TextBlock>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    

    If you need help with implementing NotifyPropertyChanged then follow this article.