Auroth21
Auroth21

Reputation: 5

TextBlock selective line coloring

I want to read a file and then, based on some conditions, mark some lines with different colors. I have found similar problems&answers, but its not written using MVVM pattern: Selective coloring on dynamic TextBlock content in WPF

I have tried:

<ScrollViewer>
  <TextBlock >
    <Run Background="{Binding Path=DiffStatus}" Text="{Binding Path=Diff,   Mode=OneWay}"/>
  </TextBlock>
</ScrollViewer>

But it is coloring whole text, not only selected lines

Upvotes: 0

Views: 29

Answers (1)

Mark Feldman
Mark Feldman

Reputation: 16148

My usual way of doing this is with an ItemsControl, you can replace the panel with a WrapPanel and the item template with a TextBlock containing all your bindings:

<ItemsControl ItemsSource="{Binding Elements}">

    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Text}">
                <TextBlock.Foreground>
                    <SolidColorBrush Color="{Binding Foreground}" />
                </TextBlock.Foreground>
            </TextBlock>
        </DataTemplate>
    </ItemsControl.ItemTemplate>

</ItemsControl>

Then back in your viewmodel you can do something like this:

public class MainViewModel
{
    public TextElement[] Elements { get; } = new TextElement[]
    {
        new TextElement{ Text="Hello World! "},
        new TextElement{ Text="This is some blue text!", Foreground=Colors.Blue }
    };
}

public class TextElement
{
    public string Text { get; set; }
    public Color Foreground { get; set; } = Colors.Black;
}

Results:

enter image description here

Obviously if you want a dynamic document then you'd replace the TextElement[] with an ObservableCollection<TextElement> and add INPC etc.

This is more heavy-weight than adding runs and spans etc, but on the plus side you can replace the item template with typed DataTemplates in your resources block which allows you to easily embed graphics or anything else you want.

The only other way I've managed to achieve this is with a generic custom behavior that binds to an ObservableCollection and manages the child GUI elements manually.

Upvotes: 3

Related Questions