Как я могу применить GradientBrush к нескольким последовательным объектам в XAML?
Вопрос
У меня есть текстовый блок и Строка, расположенные рядом друг с другом в их собственной эксклюзивной 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>
Как показано, градиент применяется к текстовому блоку отдельно от Строки.Мне нужно найти способ применить градиент к текстовому блоку и Строке за один проход - как если бы они были полностью одним и тем же объектом.В этом примере текст должен быть в основном синим, а строка - в основном оранжевым.
Решение
В 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>
Вы также можете превратить текст в путь, но тогда вы потеряете возможность изменять текст.
Другие советы
Ваша проблема в том, что текст не является вектором и поэтому не может быть объединен со строкой (любым известным мне способом).
Я считаю, что можно преобразовать текст в векторный контур в Expression Blend, а затем использовать это для создания контура обрезки над градиентом.Или, используя контур текстового вектора, как вы бы поступили со своей линией, используйте границу цвета фона с неограниченной высотой и прозрачную заливку на самом векторе.
Похоже, придется изрядно повозиться.Думали ли вы об использовании третьего цвета для объединения этих двух?Например, текстовый блок меняется с синего на оранжевый, затем в строке оранжевый на цвет фона.Возможно, вы смогли бы получить аналогичный эффект с гораздо меньшими усилиями.