0

I am creating button styles in my application, but i noticed that for every button i have to repeat the same steps again and again, i am looking for a way in the following template so that i can pass particular properties of Path element or Path for every button different but all the other elements would be same and in same order, i have tried here searching but not able to find any particular example that was helpful to me, here is the xaml :

<ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type Button}">
        <Grid x:Name="MainGrid">
            <Rectangle 
        x:Name="MainRectangle" 
        Fill="#00000000" 
        RadiusX="5" 
        RadiusY="5"/>
            <ContentPresenter 
            x:Name="Presenter" 
            HorizontalAlignment="Center" 
            VerticalAlignment="Center" 
            TextBlock.Foreground="#BB225588"/>
            <Path Name="Minimize" Data="M0,0L32,0 32,8.6899995 0,8.6899995z" Stretch="Fill" Fill="White"  StrokeThickness="2" Width="17" Height="5" VerticalAlignment="Center" HorizontalAlignment="Center"
                Stroke="White" >
            </Path>
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Effect">
                    <Setter.Value>
                        <DropShadowEffect ShadowDepth="2" Color="White"  BlurRadius="20"></DropShadowEffect>
                    </Setter.Value>
                </Setter>
            </Trigger>
            <Trigger Property="IsPressed" Value="True">
                <Setter TargetName="MainRectangle" Property="Fill" Value="{StaticResource ClickEffect}"/>
                <Setter TargetName="Minimize" Property="Stroke" Value="White" />
            </Trigger>

        </ControlTemplate.Triggers>
    </ControlTemplate>

Now in the above template what i want is some way to bind with every button the Path element properties or some way to inject the Path element different for every button, rest will remain same, so i don't want to repeat the same style again and again. How i can achieve it.

Ehsan Sajjad
  • 61,834
  • 16
  • 105
  • 160
  • http://stackoverflow.com/questions/9232502/template-binding-with-attached-properties – ASh Mar 01 '17 at 09:13
  • This [is how I do it](http://stackoverflow.com/questions/35781205/dynamic-path-icon-buttons-in-a-collection-itemtemplate-resource-w-mouseover) so your path's are saved as resources and you just implement them at each instance by piggy-backing in on the `Tag` property bound within the template. xaml only. – Chris W. Mar 01 '17 at 16:50
  • will have a look at that :) – Ehsan Sajjad Mar 01 '17 at 16:57

1 Answers1

0

You could create a custom Button control with a dependency property for each property of the Path that you want to be able to set and bind to these properties in the ControlTemplate using the TemplateBinding markup extension, e.g.:

Control:

public class PathButton : Button
{
    public static readonly DependencyProperty FillProperty =
         DependencyProperty.Register("Fill", typeof(Brush),
         typeof(PathButton), new FrameworkPropertyMetadata(Brushes.White));

    public Brush Fill
    {
        get { return (Brush)GetValue(FillProperty); }
        set { SetValue(FillProperty, value); }
    }
}

Template:

<ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type local:PathButton}">
    <Grid x:Name="MainGrid">
        <Rectangle 
                    x:Name="MainRectangle" 
                    Fill="#00000000" 
                    RadiusX="5" 
                    RadiusY="5"/>
        <ContentPresenter 
                    x:Name="Presenter" 
                    HorizontalAlignment="Center" 
                    VerticalAlignment="Center" 
                    TextBlock.Foreground="#BB225588"/>
        <Path Name="Minimize" Data="M0,0L32,0 32,8.6899995 0,8.6899995z" Stretch="Fill"
                      Fill="{TemplateBinding Fill}"
                      StrokeThickness="2" Width="17" Height="5" VerticalAlignment="Center" HorizontalAlignment="Center"
                      Stroke="White" >
        </Path>
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Effect">
                <Setter.Value>
                    <DropShadowEffect ShadowDepth="2" Color="White"  BlurRadius="20"></DropShadowEffect>
                </Setter.Value>
            </Setter>
        </Trigger>
        <Trigger Property="IsPressed" Value="True">
            <Setter TargetName="MainRectangle" Property="Fill" Value="{StaticResource ClickEffect}"/>
            <Setter TargetName="Minimize" Property="Stroke" Value="White" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

Usage:

<local:PathButton Content="content" Template="{StaticResource ButtonTemplate}" Fill="Red"  />
mm8
  • 163,881
  • 10
  • 57
  • 88
  • isn't that would be a lot of work, for example if i have 10 buttons each with different shape, all shapes i am making using Path and just the color and Data property is changed normally – Ehsan Sajjad Mar 01 '17 at 16:56
  • I don't understand you. You create a property for each setting you want to be able to change without modifying the template. Can't be simpler. What's the problem? – mm8 Mar 01 '17 at 17:05
  • I need particular properties to be injected when consuming template, for example data property of path element – Ehsan Sajjad Mar 01 '17 at 18:48
  • Then you should add a dependency property to the control and bind the Data property of the Path to it just like I showed you. Didn't you read my answer? It is exactly the same except for the type of the dependency property. – mm8 Mar 01 '17 at 19:52
  • but you have created a new type, i don't want to do that – Ehsan Sajjad Mar 02 '17 at 07:55
  • Why not? Anyway, the other option is to use attached properties: http://stackoverflow.com/questions/41789030/bind-to-event-in-part-of-a-custom-control/41790327#41790327. Then you define the dependency properties in a static class. – mm8 Mar 02 '17 at 08:11