Click here to Skip to main content
15,889,216 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
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 :


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.

What I have tried:

Here is my xaml for Template:

XML
<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>
Posted
Updated 28-Feb-17 22:56pm
Comments
Graeme_Grant 1-Mar-17 20:47pm    
Did you find a way to do it without extending a control?
Ehsan Sajjad 2-Mar-17 3:42am    
i am looking, will update you soon

1 solution

Above is a ControlTemplate and not a Style

XML
<Window.Resources>
  <SolidColorBrush x:Key="Button.Static.Background" Color="#FFFFFFFF"/>
  <SolidColorBrush x:Key="Button.Static.Border" Color="#FF333333"/>

  <Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
    <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
    <Setter Property="Foreground" Value="{DynamicResource {x:Static
                                          SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="HorizontalContentAlignment" Value="Left"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate 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>
      </Setter.Value>
    </Setter>
  </Style>

</Window.Resources>

<Button Style="{StaticResouce ButtonStyle}"/>
Now, for unique button Paths, it is best to make your own so that you can pass a Path as a DP:
C#
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace WpfNet45.Core.Controls
{
    public class PathButton : Button
    {
        static PathButton()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(PathButton), new FrameworkPropertyMetadata(typeof(PathButton)));
        }

        #region Properties

        public static readonly DependencyProperty PathDataProperty = DependencyProperty.Register
            (
                "PathData",
                typeof(Geometry),
                typeof(PathButton),
                new PropertyMetadata(null)
            );

        public Geometry PathData
        {
            get { return (Geometry) GetValue(PathDataProperty); }
            set { SetValue(PathDataProperty, value); }
        }

        public static readonly DependencyProperty PathStyleProperty = DependencyProperty.Register
            (
                "PathStyle",
                typeof(Style),
                typeof(PathButton),
                new PropertyMetadata(null)
            );

        public Style PathStyle
        {
            get { return (Style) GetValue(PathStyleProperty); }
            set { SetValue(PathStyleProperty, value); }
        }

        #endregion
    }
}
Now to use:
XML
<Window.Resources>
  <media:Geometry x:Key="Trash">M13.004038,11.999008L15.004038,11.999008 15.004038,27.999008 13.004038,27.999008z M9.0040382,11.999008L11.004038,11.999008 11.004038,27.999008 9.0040382,27.999008z M5.0040382,11.999008L7.0040382,11.999008 7.0040382,27.999008 5.0040382,27.999008z M2.0040382,9.9990084L2.0040382,29.999008 18.005991,29.999008 18.004038,9.9990084z M0.0040382088,7.9990083L20.004038,7.9990083 20.004038,29.999008C20.004038,31.102036,19.107066,31.999008,18.004038,31.999008L2.0040382,31.999008C0.90101089,31.999008,0.0040382347,31.102036,0.0040382088,29.999008z M9.382152,1.9928446C9.4311546,2.0108452,9.2901482,2.1378503,9.2241453,2.3918595L9.1588997,2.6454129 12.349724,3.4957047 12.411291,3.2568917C12.479293,2.9928818,12.41229,2.8088751,12.379289,2.7708735z M9.3526691,0.0019369125C9.5361752,-0.0065422058,9.7194179,0.01277113,9.8971762,0.060772896L12.969316,0.87780333C14.082366,1.1758142,14.686393,2.4398613,14.348379,3.7559104L14.282698,4.0108039 21.008067,5.8029819 20.492064,7.7349798 0,2.273984 0.51500203,0.34198523 7.2264289,2.1304479 7.2880572,1.8918409C7.4690656,1.189815 7.8960847,0.59879303 8.4571108,0.27178049 8.7402481,0.10739946 9.0468248,0.016067982 9.3526691,0.0019369125z</media:Geometry>

  <Style x:Key="ExPathStyle" TargetType="Path">
    <Setter Property="Fill" Value="{DynamicResource {x:Static
                                    SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="StrokeThickness" Value="0"/>
    <Setter Property="Width" Value="16"/>
    <Setter Property="Height" Value="16"/>
    <Setter Property="Stretch" Value="Uniform"/>
    <Setter Property="VerticalAlignment" Value="Center"/>
    <Setter Property="HorizontalAlignment" Value="Center"/>
    <Setter Property="SnapsToDevicePixels" Value="True"/>
  </Style>

</Window.Resources>

  <local:PathButtonEx Content="PathButtonEx" 
                      ContentPlacement="Right" 
                      PathGeometry="{StaticResource Trash}"
                      PathStyle="{StaticResource ExPathStyle}"/>
 
Share this answer
 
v3
Comments
Ehsan Sajjad 1-Mar-17 5:01am    
that is not my question, i want to specify particular element properties of my template when using it
Graeme_Grant 1-Mar-17 5:04am    
Part 1 answered the Style question. Part 2 now posted answers the Path question. Takes time to write code for examples.
Ehsan Sajjad 1-Mar-17 5:08am    
isn't it doable via xaml, i think it is doable via xaml but i am not getting the exact syntax of how to do bindings.
Graeme_Grant 1-Mar-17 5:09am    
You need to have a separate style with the path embedded for each control. That will bloat your xaml and slow your app.

This way is quick and clean and lightweight.
Graeme_Grant 1-Mar-17 5:24am    
If you Google[^] you will find answers very similar to the one that I provided.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900