如何在Silverlight中绑定GradientStop Colors或GradientStops属性?

时间:2009-10-03 14:37:33

标签: silverlight xaml binding gradient gradientstop

我希望能够在Silverlight中拥有动态渐变,例如:

<RadialGradientBrush GradientOrigin="0.20,0.5" Center="0.25,0.50" 
                     RadiusX="0.75" RadiusY="0.5">
  <GradientStop Color="{Binding Path=GradientStart}" Offset="0" />
  <GradientStop Color="{Binding Path=GradientEnd}" Offset="1" />
</RadialGradientBrush>

我绑定了两个返回“Color”类型的属性,但是我总是收到这条消息:

AG_E_PARSER_BAD_PROPERTY_VALUE

如果我尝试绑定到GradientStop Collection,这也有同样的问题,这个问题的解决方案是什么:

  1. 允许在运行时更改渐变的开始和结束
  2. 适用于Silverlight 3.0,不是WPF解决方案
  3. 如果有工作或者无论如何要复制这种行为,这是可以接受的,我有解决方案可以使用LinearGradients,因为我可以将某些“Fill”属性绑定到此 - 但是在这种情况下无效,另外,我可能会使用其他渐变类型,其他人可能会在将来使用此解决方案/替代方案。

4 个答案:

答案 0 :(得分:12)

问题是 GradientStop 不是从 FrameworkElement 派生的,因此无法绑定数据。不幸的是,这意味着你必须从代码中设置它。

答案 1 :(得分:5)

要真正做到这一点,你有两个选择。

将显示项Brush属性绑定到数据中的Brush属性

让数据源带有一个属性,该属性会为每个项目公开要使用的画笔,并绑定显示项目的属性,该属性包含画笔,例如Fill属性。如果您对Start和Stop值对的一组不同值很小,则此方法有效。您将为每对创建每个画笔的实例,然后数据项将显示正确的画笔。

使用值转换器

绑定显示项目Brush属性

如果“开始”和“停止”值为更多变量,则每个显示的项目都需要刷新类型的新实例。在这种情况下,您将使用值转换器绑定显示项刷属性,例如: -

 <Rectangle Fill="{Binding Converter={StaticResource MyBrushBuilder} }" ... >

有关构建转换器的完整说明,请参阅此answer

在这种情况下,虽然您的转换方法实现如下所示: -

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
  YourItemsType item = (YourItemsType)value;

  var start = new GradientStop();
  start.Offset = 0;
  start.Color = item.GradientStart;

  var stop = new GradientStop();
  stop.Offset = 1;
  stop.Color = item.GradientStop;

  var result = new RadialGradientBrush();
  result.GradientOrigin = new Point(0.20, 0.5);
  result.Center = new Point(0.25, 0.5);
  result.RadiusX = 0.75;
  result.RadiusY = 0.5;
  result.GradientStops = new GradientStopCollection();
  result.GradientStops.Add(start);
  result.GradientStops.Add(stop);

  return result;
}

<强>买者

每当发生数据绑定时,会为每个项目创建一组刷子。这可能是昂贵且不合需要的。因此,如果认为这种绑定转换器方法是必要的,那么我建议你使用静态的画笔字典。这本词典的关键是两种颜色的哈希。您只需在必要时创建新画笔,并尽可能重复使用以前创建的画笔。

答案 2 :(得分:0)

您是否确认了用作定义渐变画笔的DataContext的类型?由于您未在绑定中指定Source,因此默认情况下会使用DataContext

答案 3 :(得分:0)

相当古老的帖子,但它可能(现在),所以这是我的解决方案。我的XAML代码:

<Ellipse.Resources>
    <local:ColorConverter x:Key="ColorConverter"/>
</Ellipse.Resources>
<Ellipse.Fill>
    <RadialGradientBrush>
        <GradientStop Color="{Binding MenuColor2, Source={x:Static p:Settings.Default}, Converter={StaticResource ColorConverter}}" Offset="1" />
        <GradientStop Color="{Binding MenuColor1, Source={x:Static p:Settings.Default}, Converter={StaticResource ColorConverter}}" Offset="0.85" />
    </RadialGradientBrush>
</Ellipse.Fill>

这是我的C#-Code。

[ValueConversion(typeof(System.Drawing.Color), typeof(System.Windows.Media.Color))]
public class ColorConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is System.Drawing.Color)
        {
            var clr = (System.Drawing.Color)value;
            return System.Windows.Media.Color.FromArgb(clr.A, clr.R, clr.G, clr.B);
        }
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is Color)
        {
            var clr = (Color)value;
            return System.Drawing.Color.FromArgb(clr.A, clr.R, clr.G, clr.B);
        }
        return value;
    }
}