Frage

I have a RoundButtonTemplate to get buttons like the Play and Pause button of the Music player.

    <ControlTemplate x:Key="RoundButtonTemplate" TargetType="Button">
        <Grid Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}">
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="CommonStates">
                    <VisualState x:Name="Pressed">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill)" Storyboard.TargetName="ButtonBackground">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneAccentBrush}"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="Normal"/>
                    <VisualState x:Name="Disabled">
                        <Storyboard>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Opacity)" Storyboard.TargetName="ButtonBackground">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="0.5"/>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Opacity)" Storyboard.TargetName="ButtonBorder">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="0.5"/>
                            </ObjectAnimationUsingKeyFrames>
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Opacity)" Storyboard.TargetName="ButtonContent">
                                <DiscreteObjectKeyFrame KeyTime="0" Value="0.5"/>
                            </ObjectAnimationUsingKeyFrames>
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="MouseOver"/>
                </VisualStateGroup>
                <VisualStateGroup x:Name="FocusStates"/>
            </VisualStateManager.VisualStateGroups>
            <Border x:Name="ButtonBorder" BorderBrush="White" BorderThickness="3" Background="Transparent" CornerRadius="100">
                <Ellipse x:Name="ButtonBackground" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="{TemplateBinding Background}" />
            </Border>
            <ContentPresenter x:Name="ButtonContent" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
        </Grid>
    </ControlTemplate>

If the button is pressed the Background of the button should change to the foreground color and the icon which is displayed through the ContentPresenter should change to the background color or gets transparency.

Changing the background of the button to the foreground color is easy, but I don't know how to change the color of the image within the ContentPresenter?

War es hilfreich?

Lösung

Attached Properties to the rescue!

Step 1:

Create a static class that holds an attached property.

public static class Design
{
    public static readonly DependencyProperty AlternateContentProperty = DependencyProperty.RegisterAttached(
        "AlternateContent", 
        typeof (object), 
        typeof (Design), 
        null
    );

    public static void SetAlternateContent(DependencyObject element, object value)
    {
        element.SetValue(AlternateContentProperty, value);
    }

    public static object GetAlternateContent(DependencyObject element)
    {
        return element.GetValue(AlternateContentProperty);
    }
}

Step 2:

Add the alternate content to your template in another ContentPresenter, which starts off collapsed. Then in your Pressed visual state, collapse the original content and show the alternate one.

<ControlTemplate x:Key="RoundButtonTemplate"
                    TargetType="Button">
    <Grid Background="Transparent"
            Margin="{StaticResource PhoneTouchTargetOverhang}">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Pressed">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill)"
                                                        Storyboard.TargetName="ButtonBackground">
                            <DiscreteObjectKeyFrame KeyTime="0"
                                                    Value="{StaticResource PhoneAccentBrush}" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                        Storyboard.TargetName="ButtonContentAlternate">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <Visibility>Visible</Visibility>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                        Storyboard.TargetName="ButtonContent">
                            <DiscreteObjectKeyFrame KeyTime="0">
                                <DiscreteObjectKeyFrame.Value>
                                    <Visibility>Collapsed</Visibility>
                                </DiscreteObjectKeyFrame.Value>
                            </DiscreteObjectKeyFrame>
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Normal" />
                <VisualState x:Name="Disabled">
                    <Storyboard>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Opacity)"
                                                        Storyboard.TargetName="ButtonBackground">
                            <DiscreteObjectKeyFrame KeyTime="0"
                                                    Value="0.5" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Opacity)"
                                                        Storyboard.TargetName="ButtonBorder">
                            <DiscreteObjectKeyFrame KeyTime="0"
                                                    Value="0.5" />
                        </ObjectAnimationUsingKeyFrames>
                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Opacity)"
                                                        Storyboard.TargetName="ButtonContent">
                            <DiscreteObjectKeyFrame KeyTime="0"
                                                    Value="0.5" />
                        </ObjectAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="MouseOver" />
            </VisualStateGroup>
            <VisualStateGroup x:Name="FocusStates" />
        </VisualStateManager.VisualStateGroups>
        <Border x:Name="ButtonBorder"
                BorderBrush="White"
                BorderThickness="3"
                Background="Transparent"
                CornerRadius="100">
            <Ellipse x:Name="ButtonBackground"
                        HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch"
                        Fill="{TemplateBinding Background}" />
        </Border>
        <ContentPresenter x:Name="ButtonContent"
                            Content="{TemplateBinding Content}"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center" />

        <ContentPresenter x:Name="ButtonContentAlternate"
                            Content="{TemplateBinding Local:Design.AlternateContent}"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center"
                            Visibility="Collapsed" />
    </Grid>
</ControlTemplate>

Step 3:

Any button that uses this template should provide two contents.

<Button VerticalAlignment="Top"
        Template="{StaticResource RoundButtonTemplate}">

    <Local:Design.AlternateContent>
        <Rectangle Fill="Red"
                    Height="40"
                    Width="40" />
    </Local:Design.AlternateContent>

    <Rectangle Fill="Yellow"
                Height="40"
                Width="40" />
</Button>

That's it!

I hope this solves your problem :)

Andere Tipps

Try this:

    <Style x:Key="RoundButtonTemplate" TargetType="Button">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill)" Storyboard.TargetName="ButtonBackground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{Binding Foreground, RelativeSource={RelativeSource TemplatedParent}}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Opacity)" Storyboard.TargetName="ButtonContent">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="0.5"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Opacity)" Storyboard.TargetName="ButtonBackground">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="0.5"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Opacity)" Storyboard.TargetName="ButtonBorder">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="0.5"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Opacity)" Storyboard.TargetName="ButtonContent">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="0.5"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="MouseOver"/>
                            </VisualStateGroup>
                            <VisualStateGroup x:Name="FocusStates"/>
                        </VisualStateManager.VisualStateGroups>
                        <Border x:Name="ButtonBorder" BorderBrush="White" BorderThickness="3" Background="Transparent" CornerRadius="100">
                            <Ellipse x:Name="ButtonBackground" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="{TemplateBinding Background}" />
                        </Border>
                        <ContentPresenter x:Name="ButtonContent" Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

When pressed the Background of the buttons becomes of the color of the Foreground and the content modify it's opacity to 50%.

Oh, i've made a "Style" instead of a template, so, you can call it like... Other option is to change the current VisualState Pressed, it's the only modification I've made.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top