Question

I have a UserControl that I have various properties defined, so I can customise it for each copy that's on the screen. I have a path that uses a LinearGradientBrush fill. At present this is hard coded into the XAML. I already have the width and visibility of the path control as dependency objects and can easily modify these:

<Path 
    Visibility="{TemplateBinding PathAVisibility}"
    Width="{TemplateBinding PathALength}">
        <LinearGradientBrush EndPoint="0,0.5" MappingMode="RelativeToBoundingBox" StartPoint="1,0.5">
            <GradientStop Color="#07FFFFFF" Offset="0.812"/>
            <GradientStop Color="Red"/>
            <GradientStop Color="#00000000" Offset="0.993"/>
            <GradientStop Color="#FF956666" Offset="0.62"/>
        </LinearGradientBrush>...

What I'd like to do is to create a few gradients as options that I can then select as properties in the WPF XAML designer. Something like "GradA" is with the red, "GradB" is Blue, but doesn't have the transparency, etc.

With the Visibility I can see the "Visible/Hidden/Collapsed" as options to choose from in the design view, and this is the kind of thing I'm after.

This is where I'm stuck. I don't even know what this would be called, or how to approach it.

Any pointers on which direction I should be looking?

Was it helpful?

Solution

You can use an enum to provide the fixed values you want in Xaml, then you can use the PropertyChangedCallback on that enum DependencyProperty to change the Brush.

Here is a very quick example.

Code:

public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();
        DataContext = this;
    }

    public BrushType BrushType
    {
        get { return (BrushType)GetValue(BrushTypeProperty); }
        set { SetValue(BrushTypeProperty, value); }
    }

    // Using a DependencyProperty as the backing store for BrushType.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty BrushTypeProperty =
        DependencyProperty.Register("BrushType", typeof(BrushType), typeof(UserControl1)
        , new PropertyMetadata(BrushType.None, new PropertyChangedCallback(OnBrushTypeChanged)));

    private static void OnBrushTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var userControl = d as UserControl1;
        if (e.NewValue is BrushType)
        {
            userControl.MyBrush = userControl.FindResource(e.NewValue.ToString()) as Brush;
        }
    }

    public Brush MyBrush
    {
        get { return (Brush)GetValue(MyBrushProperty); }
        set { SetValue(MyBrushProperty, value); }
    }

    // Using a DependencyProperty as the backing store for MyBrush.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MyBrushProperty =
        DependencyProperty.Register("MyBrush", typeof(Brush), typeof(UserControl1), new PropertyMetadata(null));

}

public enum BrushType
{
    None,
    BrushA,
    BrushB,
    BrushC
}

Xaml:

<UserControl x:Class="WPFListBoxGroupTest.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <SolidColorBrush x:Key="BrushA" Color="Red" />
        <SolidColorBrush x:Key="BrushB" Color="Yellow" />
        <SolidColorBrush x:Key="BrushC" Color="Blue" />
    </UserControl.Resources>

    <Grid Background="{Binding MyBrush}" />

</UserControl>

Usage:

<StackPanel Orientation="Horizontal">
    <local:UserControl1 BrushType="BrushA" />
    <local:UserControl1 BrushType="BrushB" />
    <local:UserControl1 BrushType="BrushC" />
</StackPanel>

Result:

enter image description here

OTHER TIPS

One nice feature that could minimize your coding effort here are Visual States. Read about them here. There's other mechanisms to achieve this as well. A combination of styles, templates and triggers would also work, but make it harder to access UI elements in your components code behind.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top