WPF: How do I bind the color property of a gradientstop that is located in a controlTemplate in vb code?

2.1k Views Asked by At

I need to do this in order to create a dynamic background brush for a custom control (inherits ContentControl). My custom control has two dependency properties: StartColor and EndColor. In the control template for the custom control, the control is wrapped in a border that's background is a RadialGradientBrush with gradient stops. one gradient stop's color is bound to StartColor and the other's is bound to EndColor. I have this WORKING in XAML, but I need to convert it to VB code. The border element of the control template in XAML is done with the following code:

<Style x:Key="{x:Type wpf:MyControl}" 
   TargetType="{x:Type wpf:MyControl}" 
   BasedOn="{StaticResource {x:Type ContentControl}}">
    <Style.Setters>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type wpf:MyControl}">

                      ...

                    <Border HorizontalAlignment="Stretch" 
                            x:Name="background" Width="Auto"
                            Grid.RowSpan="3" 
                            Opacity="0.9" 
                            CornerRadius="{TemplateBinding CornerRadius}">
                                <Border.Background>
                                    <Custom:RadialGradientBrush>
                                        <Custom:GradientStop Color="{Binding Path=EndColor, 
                                                            RelativeSource={RelativeSource TemplatedParent}, 
                                                            Mode=OneWay}" 
                                                            Offset="0.462"/>
                                        <Custom:GradientStop Color="{Binding StartColor, 
                                                            RelativeSource={RelativeSource TemplatedParent}, 
                                                            Mode=OneWay}" 
                                                            Offset="1"/>
                                    </Custom:RadialGradientBrush>
                                </Border.Background>
                            </Border>

                        ...

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style.Setters>
</Style>

I tried to create the border in VB code as follows, but it did not work:

...
Dim backgroundBorder As New FrameworkElementFactory(GetType(Border))
        With backgroundBorder
            .Name = "background"
            .SetValue(Grid.RowSpanProperty, 3)
            .SetValue(Grid.OpacityProperty, 0.9)
            .SetBinding(Border.CornerRadiusProperty, New Binding("CornerRadius") With {.RelativeSource = New RelativeSource(RelativeSourceMode.TemplatedParent)})
        End With

        Dim backgroundBrush As New RadialGradientBrush()

        Dim startColorGradientStop As New GradientStop()
        startColorGradientStop.Offset = 1.0
        BindingOperations.SetBinding(startColorGradientStop, GradientStop.ColorProperty, New Binding("StartColor") With {.RelativeSource = New RelativeSource(RelativeSourceMode.TemplatedParent), .Mode = BindingMode.OneWay})
        backgroundBrush.GradientStops.Add(startColorGradientStop)

        Dim endColorGradientStop As New GradientStop()
        endColorGradientStop.Offset = 0.462
        BindingOperations.SetBinding(endColorGradientStop, GradientStop.ColorProperty, New Binding("EndColor") With {.RelativeSource = New RelativeSource(RelativeSourceMode.TemplatedParent), .Mode = BindingMode.OneWay})
        backgroundBrush.GradientStops.Add(endColorGradientStop)

backgroundBorder.SetValue(Border.BackgroundProperty, backgroundBrush)
...



Any ideas of how I can accomplish this in VB code?

2

There are 2 best solutions below

1
Kenan E. K. On BEST ANSWER

Do you know the FrameworkElementFactory approach is not recommended anymore, according to MS? The recommended approach is to create any element/resource in code with XamlReader.Parse.

4
Jobi Joy On

You have to access the Parent ContentControl to which the Border should be a Content. And set that in your VB code.

What I meant by ContentControl here is whichever control is the parent of the Border, you need to access that on your OnApplyTemplate override function and add your VB.NET created border as child to that visual.