TextBlock选择性线着色

时间:2019-05-26 22:06:16

标签: c# wpf mvvm data-binding

我想读取一个文件,然后根据某些条件,用不同的颜色标记一些行。 我发现了类似的问题和答案,但未使用MVVM模式编写: Selective coloring on dynamic TextBlock content in WPF

我尝试过:

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

但是它使整个文本着色,不仅是选定的行

1 个答案:

答案 0 :(得分:3)

我通常的做法是使用ItemsControl,您可以将面板替换为WrapPanel,将项目模板替换为包含所有绑定的TextBlock:

<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>

然后回到您的视图模型中,您可以执行以下操作:

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;
}

结果:

enter image description here

很明显,如果您要使用动态文档,则可以将TextElement[]替换为ObservableCollection<TextElement>并添加INPC等。

这比添加游程和跨度等更为繁重,但从正面来看,您可以在资源块中用键入的DataTemplates替换项目模板,这使您可以轻松地嵌入图形或任何其他想要的东西。

我设法实现这一目标的另一种方法是使用通用的自定义行为,该行为绑定到ObservableCollection并手动管理子GUI元素。