How to link GradientStop Colors or GradientStops in Silverlight?

I want to have a dynamic gradient in Silverlight, for example below:

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

I am contacting two properties that return a Color type, however I always get this message:

 AG_E_PARSER_BAD_PROPERTY_VALUE 

If I try to link to the GradientStop Collection, this also has the same problem, what is the solution to this problem:

  • Allows you to change the start and end gradient at run time
  • Works in Silverlight 3.0 and is not a WPF solution

If there is any work or duplication of this behavior in any case, that would be acceptable, I have solutions that work with LinearGradients, since I can just link the Fill property to something like this, but in this situation it’s not will work, plus there may be other types of gradients that I can use, while others may use in the future, to which this solution / alternative will apply.

+4
source share
4 answers

The problem is that GradientStop cannot be obtained from FrameworkElement , therefore it cannot be bound to data. Unfortunately, this means that you need to install it from the code.

+12
source

For this to happen, you have two options.

Bind Brush display elements to Brush property in data

The data source has a property that provides the brush that you want to use for each element, and you bind the property of the display element that the brush takes, say, the Fill property. This works if the set of different values ​​that you would have for pairs of Start and Stop values ​​is small. You would create an instance of each brush for each pair, and then the data element would display the correct one.

Bind Brush Display Elements Using Value Converter

If the Start and Stop values ​​mean more than a variable, you will need a new instance of the Brush type for each item displayed. In this case, you bind the brush property of the display elements using a value converter, for example: -

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

Pay attention to for a full description of the construction of the converter.

In this case, the implementation of your conversion method will look like this: -

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

Caveat

Whenever data is bound, a whole bunch of brushes are created, one for each element. This can be costly and undesirable. Therefore, if this binding converter approach is considered necessary, I would recommend using a static brush dictionary. The key to this dictionary will be a hash of two colors. If necessary, you will create a new brush and reuse the previously created brush, if possible.

+5
source

Have you confirmed that the type is used as a DataContext , where is your gradient brush defined? Since you did not specify Source in your binding, it will use the DataContext by default.

0
source

Pretty old post, but it's possible (now), so here is my solution. My XAML code:

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

And here is my 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; } } 
0
source

All Articles