Question

Here's my problem : I have created a custom control which encapsulate a "classic button". I added some custom dependency properties to my control for my "business" reasons. One of these properties is a "progress" indicator value.

When this value change to X, I want to change X percent of the background color of the control to make a progress indicator effect.

Here are pictures of what I have and what I want to have :

Initial State

With progress

And here is my actual code :

<UserControl x:Name="userControl" x:Class="MyCustomControl"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"   
Background="White"
         Padding="0"
         Margin="0"
         Width="82"
         Height="87"
     d:designWidth="82"
     d:designHeight="87" SizeChanged="userControl_SizeChanged"    
         >


<UserControl.Resources>
    <Style x:Key="ButtonStyle1" TargetType="Button">
        <Setter Property="Padding" Value="0"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid x:Name="grid" Background="Transparent">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="MouseOver"/>
                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)" Storyboard.TargetName="ButtonBackground">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Thickness>0,0,0,1</Thickness>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="grid">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Thickness>0,5,0,0</Thickness>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentContainer">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ButtonBackground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ButtonBackground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Grid>

                            <Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0,0,0,5" CornerRadius="6" Background="{TemplateBinding Background}" >
                                <ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            </Border>                                
                        </Grid>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

<Grid x:Name="LayoutRoot">

    <Button x:Name="aButton"
                Style="{StaticResource ButtonStyle1}" 
                Background="{Binding Background, ElementName=userControl}" 
                Foreground="{Binding Foreground, ElementName=userControl}" 
                BorderBrush="{Binding Foreground, ElementName=userControl}"                
                VerticalContentAlignment="Center"
                HorizontalContentAlignment="Center"
                Content="1"
                >

    </Button>

</Grid>

I can add the code behind if needed but it's just a dependency property.

How can I do that in XAML/C# ? What is the best solution ? I try to add a rectangle inside my the "Border" named "ButtonBackground" but I can't find how to get it works...

Thanks for any help !

Was it helpful?

Solution

<Grid>
    <Rectangle HorizontalAlignment="Left" Height="159" Margin="174.5,17.5,0,0" Stroke="Black" VerticalAlignment="Top" Width="152" RenderTransformOrigin="0.5,0.5" RadiusY="18.5" RadiusX="18.5">
        <Rectangle.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                <SkewTransform/>
                <RotateTransform Angle="-90"/>
                <TranslateTransform/>
            </TransformGroup>
        </Rectangle.RenderTransform>
        <Rectangle.Fill>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="Black" Offset="{Binding Value, ElementName=slider}"/>
                <GradientStop Color="White" Offset="{Binding Value, ElementName=slider}"/>
            </LinearGradientBrush>
        </Rectangle.Fill>
    </Rectangle>
    <Slider x:Name="slider" HorizontalAlignment="Left" Margin="172,207,0,0" VerticalAlignment="Top" Width="165" LargeChange="0.1" Maximum="1" TickFrequency="0.1"/>

</Grid>

Here is the Code that would help you. I have take a rectangle in my case, set its background to gradient. As gradient as two stops, I set them in such a way that both appear to be a single fill. I bind both gradient stops with a slider and customized the slider , its large change , step frequency and etc. Now as i move my slider the fill color also changes as you required. Bind both stops of gradient color to your dependance property and you would be done with it. Hope this solution might work for you.

Here are few results of what I made.

Notice the movement of slider Notice again

happy coding !

Let me know if you have some questions.

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