Question

I have a TextBlock and a Line sitting next to each other in their own exclusive StackPanel.

I need to spread my LinearGradientBrush across the two objects, rather than shading them individually.

My project currently looks like this:

http://img188.imageshack.us/img188/1268/seperategradients.png

<StackPanel Orientation="Horizontal">

    <TextBlock VerticalAlignment="Bottom">
        SomeTextContent
        <TextBlock.Foreground>
            <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                <GradientStop Offset="0" Color="Blue" />
                <GradientStop Offset="1" Color="Orange" />
            </LinearGradientBrush>
        </TextBlock.Foreground>
    </TextBlock>

    <Line VerticalAlignment="Bottom" X2="100">
        <Line.Stroke>
            <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                <GradientStop Offset="0" Color="Blue" />
                <GradientStop Offset="1" Color="Orange" />
            </LinearGradientBrush>
        </Line.Stroke>
    </Line>

</StackPanel>

As shown, the gradient is applied to TextBlock seperately from the Line. I need to find a way to apply the gradient across the TextBlock and the Line in a single pass - as if they were the same object entirely. In this example, the text should be mostly blue and the line should be mostly orange.

Was it helpful?

Solution

In WPF you can use a Visual Brush.

Add a brush resource to your window or control resources:

<Window.Resources>      
  <VisualBrush x:Key="stackPanel">
    <VisualBrush.Visual>
      <StackPanel Orientation="Horizontal">  
        <TextBlock VerticalAlignment="Bottom"> 
          SomeTextContent        
        </TextBlock>   
        <Line VerticalAlignment="Bottom" X2="100" Stroke="black"/>     
      </StackPanel>
    </VisualBrush.Visual>
  </VisualBrush>
</Window.Resources>

Next, apply that brush to the opacitymask of a rectange, for example:

  <Rectangle OpacityMask="{DynamicResource stackPanel}">
    <Rectangle.Fill>
      <LinearGradientBrush EndPoint="1.0,0.5" StartPoint="0,0.5">
        <GradientStop Color="Blue" Offset="0"/>
        <GradientStop Color="Orange" Offset="1"/>
      </LinearGradientBrush>
     </Rectangle.Fill>
  </Rectangle>

You can turn the text into a path too, but you'll loose the ability to change the text than.

OTHER TIPS

Your problem is that text is not a vector and so cannot be combined with the line (any way that I know of).

I believe that it is possible to change text into a vector path in Expression Blend and then use that to create a clipping path over the gradient. Or, using the text vector path like you would do with your line, use a background colour unrestricted-height border and transparent fill on the vector itself.

Seems like a lot of trouble to go to. Have you thought about using a third colour to merge the two? For example text block fade from Blue to Orange, then on the line Orange to the background colour. You might be able to get a similar effect for a lot less effort.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top