【问题标题】:WPF - Change the color of an entire textblock lineWPF - 更改整个文本块行的颜色
【发布时间】:2017-02-07 10:56:17
【问题描述】:

在我的 WPF 应用程序中,我有两个文本块,它们通过运行从后面的代码中填充。每隔一行应该有不同的背景颜色,这样更容易阅读。不幸的是,这些线条仅在书写时被染色。但我希望背景颜色覆盖整行,而不仅仅是书写区域。

代码:

         for (int i = 0; i < GlobalSettings.prefixList.Count; i++)
         {
            runLeft = new Run(GlobalSettings.prefixList[i].prefix + "\n");
            runRight = new Run(GlobalSettings.prefixList[i].amount + "\n");
            
            if (i % 2 == 0)
            {
                runLeft.Background = Brushes.Gray;
                runRight.Background = Brushes.Gray;
            }
            else
            {
                runLeft.Background = Brushes.LightGray;
                runRight.Background = Brushes.LightGray;
            }

            tblock_StatisticsLeft.Inlines.Add(runLeft);
            tblock_StatisticsRight.Inlines.Add(runRight);
         }

Example Picture

两个文本块在中间无缝连接在一起,因此看起来就像是单个文本块中的一行。如果这样更容易,行之间的空间可以忽略不计。

有没有不使用文本框或富文本框的解决方案?

编辑:

XAML 代码:

<UserControl x:Class="MuseKeyGenApp.UCStartUp"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:MuseKeyGenApp"
         mc:Ignorable="d"   
         Background = "#FF0069B4"
         d:DesignHeight="500" d:DesignWidth="800">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="26"/>
        <RowDefinition Height="0"/>
        <RowDefinition Height="*" MinHeight="80"/>
        <RowDefinition Height="*" MinHeight="80"/>
        <RowDefinition Height="*" MinHeight="80"/>
        <RowDefinition Height="*" MinHeight="80"/>
        <RowDefinition Height="*" MinHeight="80"/>
        <RowDefinition Height="0"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*" MinWidth="150"/>
        <ColumnDefinition Width="0.75*" MinWidth="100"/>
        <ColumnDefinition Width="0.75*" MinWidth="100"/>
        <ColumnDefinition Width="0.75*" MinWidth="100"/>
        <ColumnDefinition Width="0.75*" MinWidth="100"/>
    </Grid.ColumnDefinitions>


    <ScrollViewer Grid.Row="2" Grid.RowSpan="3" Grid.Column="1" Grid.ColumnSpan="2" Margin="10,35,12,12" Name="sv_PrefixList">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0" x:Name="tblock_StatisticsLeft" HorizontalAlignment="Stretch" LineHeight="20" TextWrapping="Wrap" Margin="0,0,0,0" Text="TextBlock" VerticalAlignment="Stretch" TextAlignment="Left"/>
            <TextBlock Grid.Column="1" x:Name="tblock_StatisticsRight" HorizontalAlignment="Stretch" LineHeight="20" TextWrapping="Wrap" Margin="0,0,10,0" Text="TextBlock" VerticalAlignment="Stretch" TextAlignment="Right"/>
        </Grid>
    </ScrollViewer>

</Grid>

我省略了控件中所有其他不相关的内容。

【问题讨论】:

  • 为什么不设置 tblock_StatisticsLeft 和 tblock_StatisticsRight TextBlocks 的 Background 属性,而不是设置 Run 元素的 Background 属性?
  • 因为整个文本块只有一种颜色,而不是每一行都有单独的颜色,因为我没有弄错。
  • TextBlocks 的背后是什么?您使用的是哪种 ItemsControl?您需要设置在 TextBlocks 后面看到的元素的背景属性。
  • 后面什么都没有。 XAML 代码:
  • TextBlock 后面当然有 something。请将您的窗口的整个 XAML 标记连同您的代码一起发布。

标签: c# wpf


【解决方案1】:

您可以(应该)使用ItemsControl。将它的 ItemsSource 属性设置为您的 GlobalSettings.prefixList 集合,即您将 for 循环替换为:

ic.ItemsSource = GlobalSettings.prefixList;

确保“前缀”和“金额”是您的“前缀”类型或您所称的任何类型的公共属性(而不是字段):

public string prefix { get; set; }

然后您将Grid 和TextBlocks 放在ItemsControlItemTemplate 中,并将TextBlocks 绑定到“prefix”和“amount”属性:

<ScrollViewer Grid.Row="2" Grid.RowSpan="3" Grid.Column="1" Grid.ColumnSpan="2" Margin="10,35,12,12" Name="sv_PrefixList">
    <ItemsControl x:Name="ic" AlternationCount="2">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid x:Name="grid">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="1*"/>
                        <ColumnDefinition Width="1*"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Column="0" x:Name="tblock_StatisticsLeft" HorizontalAlignment="Stretch" LineHeight="20" TextWrapping="Wrap" Margin="0,0,0,0" VerticalAlignment="Stretch" TextAlignment="Left"
                                       Text="{Binding prefix}"/>
                    <TextBlock Grid.Column="1" x:Name="tblock_StatisticsRight" HorizontalAlignment="Stretch" LineHeight="20" TextWrapping="Wrap" Margin="0,0,10,0" VerticalAlignment="Stretch" TextAlignment="Right"
                                       Text="{Binding amount}"/>
                </Grid>
                <DataTemplate.Triggers>
                    <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                        <Setter Property="Background" Value="Gray" TargetName="grid"/>
                    </Trigger>
                    <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                        <Setter Property="Background" Value="LightGray" TargetName="grid"/>
                    </Trigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</ScrollViewer>

这应该会给你彩色线条。

【讨论】:

  • 我会测试它,它运行完美!你知道为什么它们必须是公共属性而不能只是字段吗?
  • 不知道 ItemsControl.AlternationIndex。谢谢。
  • @Gistiv:因为你只能绑定到公共属性。
【解决方案2】:

这是正确的做法:

Xaml:

 <Window.Resources>
    <local:BackConverter x:Key="BackConverter"/>
</Window.Resources>
<Grid Margin="10">
    <ItemsControl Name="ic"> 
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <DockPanel LastChildFill="False">
               <DockPanel.Background>
                            <MultiBinding Converter="{StaticResource BackConverter}">
                                <Binding />
                                <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}"/>
                            </MultiBinding>
                        </DockPanel.Background>
                    <TextBlock DockPanel.Dock="Left" Text="{Binding Left}">
                    </TextBlock>
                    <TextBlock DockPanel.Dock="Right" Text="{Binding Right}">
                    </TextBlock>
                </DockPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

c#代码:

  public class obj
    {
        public string Left { get; set; }
        public string Right { get; set; }
    }

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;

        List<obj> objects = new List<obj>();
        for (int i = 0; i < 10; i++)
        {
            var left = "aaaaa";
            var right = "bbbbb";
            objects.Add(new obj() { Left = left, Right = right }); 
        }
        ic.ItemsSource = objects;

    }

转换器:

public class BackConverter : IMultiValueConverter
{

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var index = ((ItemsControl)values[1]).Items.IndexOf(values[0]);
        if (index % 2 == 0)
            return Brushes.Gray;
        return Brushes.White; 
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    } 
}

【讨论】:

  • 感谢您的努力。我试过了,但没有给我想要的结果。颜色仍然只是在文本所在的位置染色,我想整行染色。
  • 你是对的。它很容易修复:将背景部分设置为堆栈面板的背景。
猜你喜欢
  • 2019-04-20
  • 1970-01-01
  • 1970-01-01
  • 2015-01-10
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
  • 2012-10-26
  • 1970-01-01
相关资源
最近更新 更多