Tuesday, April 24, 2012

"Dynamic" LinearGradientBrush using a public class

(Still working on this - more info later. Below is the code to create the effect)

1. Create a new class object in Blend (or Visual Studio). (Such as ElementItems.cs)
2. In the class, create a public class (such as public class LinearBrushItems... full example below)

namespace ThisApplication
{
   public class ElementItems
    {
       public ElementItems()
        {
         }

       public class LinearBrushItems
      {
           // the line below extracts the EndPoint for the brush. This is why it is defined as a Point
            public Point EndPoint {get; set;}
           // the line below extracts the StartPoint for the brush. This is why it is defined as a Point
           public Point StartPoint {get; set;}
           // sets the GradientStopCollection for the brush
           // the GradientStopCollection defines the GradientStops for the brush, and the colors
           public GradientStopCollection GradientStopCollection {get; set;}
      }
}


The GradientStopCollection is defined in a Resource Dictionary. It is implied in a LinearGradientBrush definition - if the entire framework of the LinearGradientBrush was displayed it would be:

<LinearGradientBrush EndPoint="0,0" StartPoint="1,1">
   <GradientStopCollection >
        <GradientStop Color="Blue" Offset="0.296"/>
        <GradientStop Color="Yellow" Offset="0.985"/>
        <GradientStop Color="Green" Offset="0.041"/>
        <GradientStop Color="Red" Offset="0.696"/>
        <GradientStop Color="White" Offset="0.307"/>
        <GradientStop Color="Black" Offset="0.744"/>
    </GradientStopCollection>
</LinearGradientBrush>

Giving the GradientStopCollection a key, and defining in a Resource Dictionary, can be reused without creating a new brush. 

<GradientStopCollection x:Key="RainbowGradientOne">
        <GradientStop Color="Blue" Offset="0.296"/>
        <GradientStop Color="Yellow" Offset="0.985"/>
        <GradientStop Color="Green" Offset="0.041"/>
        <GradientStop Color="Red" Offset="0.696"/>
        <GradientStop Color="White" Offset="0.307"/>
        <GradientStop Color="Black" Offset="0.744"/>
    </GradientStopCollection>



:NOTE:
If there are any LinearGradientBrushes that are an exact duplicate of the GradientStops defined in the GradientStopCollection you will see the error "Value does not fall within the expected range". For example: if the LinearGradientBrush and the GradientStopCollection in this example were defined in the same application (even if in different Resource Dictionaries) - the application will throw this error.

When I got that error, I looked all over and read several possible fixes. When Blend gave me that error - after hitting ok when it asked to see the results panel, that is the error it gave.
It did give another error before I hit the ok on the dialog window. By increasing the results window before building, I was able to see the initial error - which gave the explanation that there was a duplicate definition.

To use the class in a UserControl (haven't tried in a page yet)

<UserControl
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:local = "clr-namespace:This Application"
 x:Class="ThisApplication.GradientTest"/>

<UserControl.Resources>
<!-- The local definition for the LinearGradientBrush Elements HAS to have a key associated with it -->
<local:LinearBrushItems x:Key="BasicRainbowGradient"
                                          EndPoint="0,0"
                                          StartPoint="1,1"
                                          GradientStopCollection="{StaticResource RainbowGradientOne}" />
</UserControl.Resources>

<Border x:Name="ThisBorder">
   <Border.Background>
<LinearGradientBrush
               EndPoint="{Binding Source={StaticResource BasicRainbowGradient}, Path=EndPoint}"
               StartPoint="{Binding Source={StaticResource BasicRainbowGradient}, Path=StartPoint}"
              GradientStops="{Binding Source={StaticResource BasicRainbowGradient}, Path=GradientStopCollection}" />
            </Border.Background>
</Border>
</UserControl>

This will give the LinearGradientBrush the elements defined in the "BasicRainbowGradient" defined in the UserControl.Resources.
          



No comments:

Post a Comment