Как применить GradientBrush к нескольким последовательным объектам в XAML?

У меня есть TextBlock и Line, расположенные рядом друг с другом в их собственной эксклюзивной StackPanel.

Мне нужно распределить LinearGradientBrush по двум объектам, а не затенять их по отдельности.

Мой проект в настоящее время выглядит так:

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>

Как показано, градиент применяется к TextBlock отдельно от Line. Мне нужно найти способ применить градиент к TextBlock и Line за один проход, как если бы они были одним и тем же объектом. В этом примере текст должен быть преимущественно синим, а линия — оранжевым.


person Giffyguy    schedule 20.09.2009    source источник
comment
Вы используете WPF или Silverlight?   -  person Sorskoot    schedule 22.09.2009


Ответы (2)


В WPF вы можете использовать визуальную кисть.

Добавьте ресурс кисти в окно или ресурсы управления:

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

Затем примените эту кисть к непрозрачной маске прямоугольника, например:

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

Вы также можете превратить текст в путь, но вы потеряете возможность изменить текст.

person Sorskoot    schedule 22.09.2009

Ваша проблема в том, что текст не является вектором и поэтому не может быть объединен с линией (как я знаю).

Я считаю, что можно преобразовать текст в векторный контур в Expression Blend, а затем использовать его для создания обтравочного контура поверх градиента. Или, используя контур текстового вектора, как если бы вы делали это со своей линией, используйте границу неограниченной высоты фонового цвета и прозрачную заливку самого вектора.

Кажется, впереди много неприятностей. Вы не думали об использовании третьего цвета для слияния двух? Например, текстовый блок меняется с синего на оранжевый, а затем на строку с оранжевым на цвет фона. Возможно, вы сможете получить аналогичный эффект с гораздо меньшими усилиями.

person MLT    schedule 22.09.2009