0
votes

I've got a ListBox that uses a Style to define how the ListBoxItems look. Here is the style:


<Style x:Key="OutputListBoxStyle" TargetType="ListBox">
  <Setter Property="TextElement.FontFamily" Value="Consolas" />
  <Setter Property="TextElement.FontSize" Value="12" />
  <Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True" />
  <Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling" />
  <Setter Property="hyp:ListBoxSelector.Enabled" Value="True" />
  <Setter Property="ItemContainerStyle" Value="{StaticResource OutputListBoxItemStyle}" />
  <Setter Property="ContextMenu">
    <Setter.Value>
      <ContextMenu>
        <MenuItem Command="Copy" />
      </ContextMenu>
    </Setter.Value>
  </Setter>
</Style>

<Style x:Key="OutputListBoxItemStyle" TargetType="ListBoxItem">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="ListBoxItem">
        <TextBlock Text="{Binding Text}" TextWrapping="Wrap"
          Background="{TemplateBinding Background}"
          Foreground="{Binding ForegroundColor}"
          FontWeight="{TemplateBinding FontWeight}"/>
        <ControlTemplate.Triggers>
          <Trigger Property="IsSelected" Value="true">
            <Setter Property="Background" Value="Blue" />
            <Setter Property="Foreground" Value="{StaticResource {x:Static SystemColors.HighlightTextBrushKey}}" />
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

As you can see, the Foreground property of the TextBlock within the ListBoxItem is binding to my object's ForegroundColor property. I've also tried binding with a Setter in the ListBoxItem itself instead of the TextBlock, and having the TextBlock use a TemplateBinding like the Background property, but this also doesn't work. Here is the object I am binding to:


public class PrintInfo : ViewModelBase
{
    protected Brush foreColor;

    public String Text { get; set; }
    public Brush ForegroundColor { get { return foreColor; } set { foreColor = value; RaisePropertyChanged("ForegroundColor"); } }

    public PrintInfo()
    {
        ForegroundColor = Brushes.White;
    }

    public PrintInfo(String text) : base()
    {
        Text = text;
    }
}

The text is being printed, but with no foreground color, so it isn't visible. I want the foreground color to be white. I've seen other SO questions that bind in a very similar way to what I'm trying to do, so I'm confused why this isn't working. Here's the ListBox itself:


<ListBox Name="OutputBox" Grid.Column="0" ItemsSource="{Binding Output,RelativeSource={RelativeSource FindAncestor,AncestorType=Window}}"
                  ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Visible"
                  Background="{DynamicResource ControlBackgroundBrush}"
                  Style="{StaticResource OutputListBoxStyle}">

EDIT 1: Added the ListBox's style to this example per Rohit's request.
EDIT 2: Just so people don't have to search through my comments, the problem wasn't in any of my XAML, it was in my custom object, PrintInfo. I was calling : base() instead of : this(), and expecting the default constructor to be called, which of course it wasn't, the superclass constructor was being called. The Foreground color was never set because of this, and thus my invisible text results.

1
How do you know that the text is being printed if it isn't visible? Did you use something like Snoop? If you hard-code the foreground in the XAML, does your text appear? I don't see anything wrong with what you have shown.TyCobb
@TyCobb Two things show me the text is printing: when I hardcode the color, it shows up, and when I don't, I can select the ListBoxItems and they change to the highlight trigger color which makes them visible.Darkhydro

1 Answers

1
votes

In your code, ListBoxItem style is not applied anywhere on ListBox instance. Moreover, I don't see any need to override the Template of ListBoxItem, you can set the ItemTemplate like this:

<ListBox Name="OutputBox" Grid.Column="0"
         ItemsSource="{Binding Output, RelativeSource={RelativeSource FindAncestor, 
                                                                AncestorType=Window}}"
         ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
         ScrollViewer.VerticalScrollBarVisibility="Visible"
         Background="{DynamicResource ControlBackgroundBrush}"
         Style="{StaticResource OutputListBoxStyle}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Text}" TextWrapping="Wrap">
                <TextBlock.Style>
                    <Style TargetType="TextBlock">
                        <Setter Property="Foreground" Value="{Binding ForegroundColor}"/>
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType=ListBoxItem}}"
                                         Value="True">
                                <Setter Property="Background" Value="Blue" />
                                <Setter Property="Foreground" Value="{StaticResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </TextBlock.Style>
            </TextBlock>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>