How to use BasedOn to template a toggle button in Generic.xaml?












0















wpf C# xaml



In my Generic.xaml, I have many styles of the form:



  <Style x:Key="ToggleButtonStyle12" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid>
<Path x:Name="path1" Data="{StaticResource InsideQuarter3}" Fill="DarkOrange" Stroke="Black" />
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="path1" Property = "Opacity" Value="0.4"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Blink_On}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource Blink_Off}"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>


The only difference between all these toggle buttons is the Path definition and the Fill color.



Could this style be templated/simplified in such a way where only the Path and Fill color need be supplied?



That is something along the lines of :



<Style x:Key="ToggleButtonStyle12" BasedOn(??????)>
<Setter Property = "Path" Value="InsideQuarter3"/>
<Setter Property = "Fill" Value="DarkOrange"/>
</Style>


Thank you for any help.



Edit#1
Well, I thought I had it--I was wrong. The below code will correctly set the Path Data and Fill properties. However, only the first created ToggleButton keeps the "MouseOver" and other ControlTemplate.Triggers. I need ALL the toggle buttons in the RingControl to respect their own triggers.



  public static class ButtonProperties
{
public static Color GetMyForegroundColor(DependencyObject obj)
{
return (Color)obj.GetValue(MyForegroundColorProperty);
}

public static void SetMyForegroundColor(DependencyObject obj, Color value)
{
obj.SetValue(MyForegroundColorProperty, value);
}

// Using a DependencyProperty as the backing store for MyForegroundColor. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MyForegroundColorProperty =
DependencyProperty.RegisterAttached("MyForegroundColor", typeof(Color), typeof(ButtonProperties), new PropertyMetadata(Colors.Black));



public static Geometry GetData(DependencyObject obj)
{
return (Geometry)obj.GetValue(DataProperty);
}

public static void SetData(DependencyObject obj, Geometry value)
{
obj.SetValue(DataProperty, value);
}

// Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataProperty =
DependencyProperty.RegisterAttached("Data", typeof(Geometry), typeof(ButtonProperties), new PropertyMetadata(null));



public static Brush GetFill(DependencyObject obj)
{
return (Brush)obj.GetValue(FillProperty);
}

public static void SetFill(DependencyObject obj, Brush value)
{
obj.SetValue(FillProperty, value);
}

// Using a DependencyProperty as the backing store for Fill. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FillProperty =
DependencyProperty.RegisterAttached("Fill", typeof(Brush), typeof(ButtonProperties), new PropertyMetadata(null));

}


Generic.xaml -- BaseButtonStyle



  <Style x:Key="BaseButtonStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="local:ButtonProperties.MyForegroundColor" Value="Blue"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid>
<TextBlock Text="Some Text">
<TextBlock.Foreground>
<SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.MyForegroundColor)}" />
</TextBlock.Foreground>
</TextBlock>

<Path x:Name="path1" Data="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.Data)}"
Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.Fill)}"
Stroke="Black"/>

<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="path1" Property = "Opacity" Value="0.4"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Blink_On}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource Blink_Off}"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>


Generic.xaml -- ModifiedButtonStyle1



 <Style x:Key="ModifiedButtonStyle1" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="local:ButtonProperties.MyForegroundColor" Value="Red" />
<Setter Property="local:ButtonProperties.Data" Value="{StaticResource Arc0}" />
<Setter Property="local:ButtonProperties.Fill" Value="LightGreen"/>
</Style>
<Style x:Key="ModifiedButtonStyle2" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="local:ButtonProperties.MyForegroundColor" Value="Red" />
<Setter Property="local:ButtonProperties.Data" Value="{StaticResource Arc45}" />
<Setter Property="local:ButtonProperties.Fill" Value="LightPink"/>
</Style>
<Style x:Key="ModifiedButtonStyle3" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="local:ButtonProperties.MyForegroundColor" Value="Red" />
<Setter Property="local:ButtonProperties.Data" Value="{StaticResource Arc90}" />
<Setter Property="local:ButtonProperties.Fill" Value="LightCoral"/>
</Style>


Generic.xaml -- Using the ModifiedButtonStyles in a custom control, RingControl



 <Style TargetType="{x:Type local:RingButtons2}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:RingButtons2}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">

<Viewbox>
<Grid>
<!--Outer Rim -->
<Path Data="{StaticResource OuterRim}" Fill="Silver" Stroke="Black" />
<Path Data="{StaticResource OuterWheelBackground}" Fill="White" Stroke="Black" />

<ToggleButton x:Name="PART_Button1" Style="{StaticResource ModifiedButtonStyle1}"/>
<ToggleButton x:Name="PART_Button2" Style="{StaticResource ModifiedButtonStyle2}"/>
<ToggleButton x:Name="PART_Button3" Style="{StaticResource ModifiedButtonStyle3}"/>
........................................................
</Grid>
</Viewbox>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>


Using the RingControl2 in the user interface:



       <w:RingButtons2/>


It would appear that clicking anywhere in the RingButtons2 control results only in the first defined togglebutton responding -- not any of the others.



How can I fix this so that each of the togglebuttons acts independently of the others and respects its own controltemplate triggers?



Thanks again.



Edit#2



Upon removing the TextBlock definition from the BaseButtonStyle,



 <TextBlock Text="Some Text">
<TextBlock.Foreground>
<SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.MyForegroundColor)}" />
</TextBlock.Foreground>
</TextBlock>


ALL WORKS! Why is this??



Thanks.










share|improve this question





























    0















    wpf C# xaml



    In my Generic.xaml, I have many styles of the form:



      <Style x:Key="ToggleButtonStyle12" TargetType="{x:Type ToggleButton}">
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="{x:Type ToggleButton}">
    <Grid>
    <Path x:Name="path1" Data="{StaticResource InsideQuarter3}" Fill="DarkOrange" Stroke="Black" />
    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True"
    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
    </Grid>
    <ControlTemplate.Triggers>
    <Trigger Property="IsMouseOver" Value="true">
    <Setter TargetName="path1" Property = "Opacity" Value="0.4"/>
    </Trigger>
    <Trigger Property="IsChecked" Value="true">
    <Trigger.EnterActions>
    <BeginStoryboard Storyboard="{StaticResource Blink_On}"/>
    </Trigger.EnterActions>
    <Trigger.ExitActions>
    <BeginStoryboard Storyboard="{StaticResource Blink_Off}"/>
    </Trigger.ExitActions>
    </Trigger>
    </ControlTemplate.Triggers>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>


    The only difference between all these toggle buttons is the Path definition and the Fill color.



    Could this style be templated/simplified in such a way where only the Path and Fill color need be supplied?



    That is something along the lines of :



    <Style x:Key="ToggleButtonStyle12" BasedOn(??????)>
    <Setter Property = "Path" Value="InsideQuarter3"/>
    <Setter Property = "Fill" Value="DarkOrange"/>
    </Style>


    Thank you for any help.



    Edit#1
    Well, I thought I had it--I was wrong. The below code will correctly set the Path Data and Fill properties. However, only the first created ToggleButton keeps the "MouseOver" and other ControlTemplate.Triggers. I need ALL the toggle buttons in the RingControl to respect their own triggers.



      public static class ButtonProperties
    {
    public static Color GetMyForegroundColor(DependencyObject obj)
    {
    return (Color)obj.GetValue(MyForegroundColorProperty);
    }

    public static void SetMyForegroundColor(DependencyObject obj, Color value)
    {
    obj.SetValue(MyForegroundColorProperty, value);
    }

    // Using a DependencyProperty as the backing store for MyForegroundColor. This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MyForegroundColorProperty =
    DependencyProperty.RegisterAttached("MyForegroundColor", typeof(Color), typeof(ButtonProperties), new PropertyMetadata(Colors.Black));



    public static Geometry GetData(DependencyObject obj)
    {
    return (Geometry)obj.GetValue(DataProperty);
    }

    public static void SetData(DependencyObject obj, Geometry value)
    {
    obj.SetValue(DataProperty, value);
    }

    // Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
    DependencyProperty.RegisterAttached("Data", typeof(Geometry), typeof(ButtonProperties), new PropertyMetadata(null));



    public static Brush GetFill(DependencyObject obj)
    {
    return (Brush)obj.GetValue(FillProperty);
    }

    public static void SetFill(DependencyObject obj, Brush value)
    {
    obj.SetValue(FillProperty, value);
    }

    // Using a DependencyProperty as the backing store for Fill. This enables animation, styling, binding, etc...
    public static readonly DependencyProperty FillProperty =
    DependencyProperty.RegisterAttached("Fill", typeof(Brush), typeof(ButtonProperties), new PropertyMetadata(null));

    }


    Generic.xaml -- BaseButtonStyle



      <Style x:Key="BaseButtonStyle" TargetType="{x:Type ToggleButton}">
    <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Blue"/>
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="{x:Type ToggleButton}">
    <Grid>
    <TextBlock Text="Some Text">
    <TextBlock.Foreground>
    <SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.MyForegroundColor)}" />
    </TextBlock.Foreground>
    </TextBlock>

    <Path x:Name="path1" Data="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.Data)}"
    Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.Fill)}"
    Stroke="Black"/>

    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True"
    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
    </Grid>
    <ControlTemplate.Triggers>
    <Trigger Property="IsMouseOver" Value="true">
    <Setter TargetName="path1" Property = "Opacity" Value="0.4"/>
    </Trigger>
    <Trigger Property="IsChecked" Value="true">
    <Trigger.EnterActions>
    <BeginStoryboard Storyboard="{StaticResource Blink_On}"/>
    </Trigger.EnterActions>
    <Trigger.ExitActions>
    <BeginStoryboard Storyboard="{StaticResource Blink_Off}"/>
    </Trigger.ExitActions>
    </Trigger>
    </ControlTemplate.Triggers>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>


    Generic.xaml -- ModifiedButtonStyle1



     <Style x:Key="ModifiedButtonStyle1" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}">
    <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Red" />
    <Setter Property="local:ButtonProperties.Data" Value="{StaticResource Arc0}" />
    <Setter Property="local:ButtonProperties.Fill" Value="LightGreen"/>
    </Style>
    <Style x:Key="ModifiedButtonStyle2" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}">
    <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Red" />
    <Setter Property="local:ButtonProperties.Data" Value="{StaticResource Arc45}" />
    <Setter Property="local:ButtonProperties.Fill" Value="LightPink"/>
    </Style>
    <Style x:Key="ModifiedButtonStyle3" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}">
    <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Red" />
    <Setter Property="local:ButtonProperties.Data" Value="{StaticResource Arc90}" />
    <Setter Property="local:ButtonProperties.Fill" Value="LightCoral"/>
    </Style>


    Generic.xaml -- Using the ModifiedButtonStyles in a custom control, RingControl



     <Style TargetType="{x:Type local:RingButtons2}">
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="{x:Type local:RingButtons2}">
    <Border Background="{TemplateBinding Background}"
    BorderBrush="{TemplateBinding BorderBrush}"
    BorderThickness="{TemplateBinding BorderThickness}">

    <Viewbox>
    <Grid>
    <!--Outer Rim -->
    <Path Data="{StaticResource OuterRim}" Fill="Silver" Stroke="Black" />
    <Path Data="{StaticResource OuterWheelBackground}" Fill="White" Stroke="Black" />

    <ToggleButton x:Name="PART_Button1" Style="{StaticResource ModifiedButtonStyle1}"/>
    <ToggleButton x:Name="PART_Button2" Style="{StaticResource ModifiedButtonStyle2}"/>
    <ToggleButton x:Name="PART_Button3" Style="{StaticResource ModifiedButtonStyle3}"/>
    ........................................................
    </Grid>
    </Viewbox>
    </Border>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>


    Using the RingControl2 in the user interface:



           <w:RingButtons2/>


    It would appear that clicking anywhere in the RingButtons2 control results only in the first defined togglebutton responding -- not any of the others.



    How can I fix this so that each of the togglebuttons acts independently of the others and respects its own controltemplate triggers?



    Thanks again.



    Edit#2



    Upon removing the TextBlock definition from the BaseButtonStyle,



     <TextBlock Text="Some Text">
    <TextBlock.Foreground>
    <SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.MyForegroundColor)}" />
    </TextBlock.Foreground>
    </TextBlock>


    ALL WORKS! Why is this??



    Thanks.










    share|improve this question



























      0












      0








      0


      1






      wpf C# xaml



      In my Generic.xaml, I have many styles of the form:



        <Style x:Key="ToggleButtonStyle12" TargetType="{x:Type ToggleButton}">
      <Setter Property="Template">
      <Setter.Value>
      <ControlTemplate TargetType="{x:Type ToggleButton}">
      <Grid>
      <Path x:Name="path1" Data="{StaticResource InsideQuarter3}" Fill="DarkOrange" Stroke="Black" />
      <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True"
      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
      </Grid>
      <ControlTemplate.Triggers>
      <Trigger Property="IsMouseOver" Value="true">
      <Setter TargetName="path1" Property = "Opacity" Value="0.4"/>
      </Trigger>
      <Trigger Property="IsChecked" Value="true">
      <Trigger.EnterActions>
      <BeginStoryboard Storyboard="{StaticResource Blink_On}"/>
      </Trigger.EnterActions>
      <Trigger.ExitActions>
      <BeginStoryboard Storyboard="{StaticResource Blink_Off}"/>
      </Trigger.ExitActions>
      </Trigger>
      </ControlTemplate.Triggers>
      </ControlTemplate>
      </Setter.Value>
      </Setter>
      </Style>


      The only difference between all these toggle buttons is the Path definition and the Fill color.



      Could this style be templated/simplified in such a way where only the Path and Fill color need be supplied?



      That is something along the lines of :



      <Style x:Key="ToggleButtonStyle12" BasedOn(??????)>
      <Setter Property = "Path" Value="InsideQuarter3"/>
      <Setter Property = "Fill" Value="DarkOrange"/>
      </Style>


      Thank you for any help.



      Edit#1
      Well, I thought I had it--I was wrong. The below code will correctly set the Path Data and Fill properties. However, only the first created ToggleButton keeps the "MouseOver" and other ControlTemplate.Triggers. I need ALL the toggle buttons in the RingControl to respect their own triggers.



        public static class ButtonProperties
      {
      public static Color GetMyForegroundColor(DependencyObject obj)
      {
      return (Color)obj.GetValue(MyForegroundColorProperty);
      }

      public static void SetMyForegroundColor(DependencyObject obj, Color value)
      {
      obj.SetValue(MyForegroundColorProperty, value);
      }

      // Using a DependencyProperty as the backing store for MyForegroundColor. This enables animation, styling, binding, etc...
      public static readonly DependencyProperty MyForegroundColorProperty =
      DependencyProperty.RegisterAttached("MyForegroundColor", typeof(Color), typeof(ButtonProperties), new PropertyMetadata(Colors.Black));



      public static Geometry GetData(DependencyObject obj)
      {
      return (Geometry)obj.GetValue(DataProperty);
      }

      public static void SetData(DependencyObject obj, Geometry value)
      {
      obj.SetValue(DataProperty, value);
      }

      // Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc...
      public static readonly DependencyProperty DataProperty =
      DependencyProperty.RegisterAttached("Data", typeof(Geometry), typeof(ButtonProperties), new PropertyMetadata(null));



      public static Brush GetFill(DependencyObject obj)
      {
      return (Brush)obj.GetValue(FillProperty);
      }

      public static void SetFill(DependencyObject obj, Brush value)
      {
      obj.SetValue(FillProperty, value);
      }

      // Using a DependencyProperty as the backing store for Fill. This enables animation, styling, binding, etc...
      public static readonly DependencyProperty FillProperty =
      DependencyProperty.RegisterAttached("Fill", typeof(Brush), typeof(ButtonProperties), new PropertyMetadata(null));

      }


      Generic.xaml -- BaseButtonStyle



        <Style x:Key="BaseButtonStyle" TargetType="{x:Type ToggleButton}">
      <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Blue"/>
      <Setter Property="Template">
      <Setter.Value>
      <ControlTemplate TargetType="{x:Type ToggleButton}">
      <Grid>
      <TextBlock Text="Some Text">
      <TextBlock.Foreground>
      <SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.MyForegroundColor)}" />
      </TextBlock.Foreground>
      </TextBlock>

      <Path x:Name="path1" Data="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.Data)}"
      Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.Fill)}"
      Stroke="Black"/>

      <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True"
      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
      </Grid>
      <ControlTemplate.Triggers>
      <Trigger Property="IsMouseOver" Value="true">
      <Setter TargetName="path1" Property = "Opacity" Value="0.4"/>
      </Trigger>
      <Trigger Property="IsChecked" Value="true">
      <Trigger.EnterActions>
      <BeginStoryboard Storyboard="{StaticResource Blink_On}"/>
      </Trigger.EnterActions>
      <Trigger.ExitActions>
      <BeginStoryboard Storyboard="{StaticResource Blink_Off}"/>
      </Trigger.ExitActions>
      </Trigger>
      </ControlTemplate.Triggers>
      </ControlTemplate>
      </Setter.Value>
      </Setter>
      </Style>


      Generic.xaml -- ModifiedButtonStyle1



       <Style x:Key="ModifiedButtonStyle1" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}">
      <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Red" />
      <Setter Property="local:ButtonProperties.Data" Value="{StaticResource Arc0}" />
      <Setter Property="local:ButtonProperties.Fill" Value="LightGreen"/>
      </Style>
      <Style x:Key="ModifiedButtonStyle2" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}">
      <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Red" />
      <Setter Property="local:ButtonProperties.Data" Value="{StaticResource Arc45}" />
      <Setter Property="local:ButtonProperties.Fill" Value="LightPink"/>
      </Style>
      <Style x:Key="ModifiedButtonStyle3" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}">
      <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Red" />
      <Setter Property="local:ButtonProperties.Data" Value="{StaticResource Arc90}" />
      <Setter Property="local:ButtonProperties.Fill" Value="LightCoral"/>
      </Style>


      Generic.xaml -- Using the ModifiedButtonStyles in a custom control, RingControl



       <Style TargetType="{x:Type local:RingButtons2}">
      <Setter Property="Template">
      <Setter.Value>
      <ControlTemplate TargetType="{x:Type local:RingButtons2}">
      <Border Background="{TemplateBinding Background}"
      BorderBrush="{TemplateBinding BorderBrush}"
      BorderThickness="{TemplateBinding BorderThickness}">

      <Viewbox>
      <Grid>
      <!--Outer Rim -->
      <Path Data="{StaticResource OuterRim}" Fill="Silver" Stroke="Black" />
      <Path Data="{StaticResource OuterWheelBackground}" Fill="White" Stroke="Black" />

      <ToggleButton x:Name="PART_Button1" Style="{StaticResource ModifiedButtonStyle1}"/>
      <ToggleButton x:Name="PART_Button2" Style="{StaticResource ModifiedButtonStyle2}"/>
      <ToggleButton x:Name="PART_Button3" Style="{StaticResource ModifiedButtonStyle3}"/>
      ........................................................
      </Grid>
      </Viewbox>
      </Border>
      </ControlTemplate>
      </Setter.Value>
      </Setter>
      </Style>


      Using the RingControl2 in the user interface:



             <w:RingButtons2/>


      It would appear that clicking anywhere in the RingButtons2 control results only in the first defined togglebutton responding -- not any of the others.



      How can I fix this so that each of the togglebuttons acts independently of the others and respects its own controltemplate triggers?



      Thanks again.



      Edit#2



      Upon removing the TextBlock definition from the BaseButtonStyle,



       <TextBlock Text="Some Text">
      <TextBlock.Foreground>
      <SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.MyForegroundColor)}" />
      </TextBlock.Foreground>
      </TextBlock>


      ALL WORKS! Why is this??



      Thanks.










      share|improve this question
















      wpf C# xaml



      In my Generic.xaml, I have many styles of the form:



        <Style x:Key="ToggleButtonStyle12" TargetType="{x:Type ToggleButton}">
      <Setter Property="Template">
      <Setter.Value>
      <ControlTemplate TargetType="{x:Type ToggleButton}">
      <Grid>
      <Path x:Name="path1" Data="{StaticResource InsideQuarter3}" Fill="DarkOrange" Stroke="Black" />
      <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True"
      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
      </Grid>
      <ControlTemplate.Triggers>
      <Trigger Property="IsMouseOver" Value="true">
      <Setter TargetName="path1" Property = "Opacity" Value="0.4"/>
      </Trigger>
      <Trigger Property="IsChecked" Value="true">
      <Trigger.EnterActions>
      <BeginStoryboard Storyboard="{StaticResource Blink_On}"/>
      </Trigger.EnterActions>
      <Trigger.ExitActions>
      <BeginStoryboard Storyboard="{StaticResource Blink_Off}"/>
      </Trigger.ExitActions>
      </Trigger>
      </ControlTemplate.Triggers>
      </ControlTemplate>
      </Setter.Value>
      </Setter>
      </Style>


      The only difference between all these toggle buttons is the Path definition and the Fill color.



      Could this style be templated/simplified in such a way where only the Path and Fill color need be supplied?



      That is something along the lines of :



      <Style x:Key="ToggleButtonStyle12" BasedOn(??????)>
      <Setter Property = "Path" Value="InsideQuarter3"/>
      <Setter Property = "Fill" Value="DarkOrange"/>
      </Style>


      Thank you for any help.



      Edit#1
      Well, I thought I had it--I was wrong. The below code will correctly set the Path Data and Fill properties. However, only the first created ToggleButton keeps the "MouseOver" and other ControlTemplate.Triggers. I need ALL the toggle buttons in the RingControl to respect their own triggers.



        public static class ButtonProperties
      {
      public static Color GetMyForegroundColor(DependencyObject obj)
      {
      return (Color)obj.GetValue(MyForegroundColorProperty);
      }

      public static void SetMyForegroundColor(DependencyObject obj, Color value)
      {
      obj.SetValue(MyForegroundColorProperty, value);
      }

      // Using a DependencyProperty as the backing store for MyForegroundColor. This enables animation, styling, binding, etc...
      public static readonly DependencyProperty MyForegroundColorProperty =
      DependencyProperty.RegisterAttached("MyForegroundColor", typeof(Color), typeof(ButtonProperties), new PropertyMetadata(Colors.Black));



      public static Geometry GetData(DependencyObject obj)
      {
      return (Geometry)obj.GetValue(DataProperty);
      }

      public static void SetData(DependencyObject obj, Geometry value)
      {
      obj.SetValue(DataProperty, value);
      }

      // Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc...
      public static readonly DependencyProperty DataProperty =
      DependencyProperty.RegisterAttached("Data", typeof(Geometry), typeof(ButtonProperties), new PropertyMetadata(null));



      public static Brush GetFill(DependencyObject obj)
      {
      return (Brush)obj.GetValue(FillProperty);
      }

      public static void SetFill(DependencyObject obj, Brush value)
      {
      obj.SetValue(FillProperty, value);
      }

      // Using a DependencyProperty as the backing store for Fill. This enables animation, styling, binding, etc...
      public static readonly DependencyProperty FillProperty =
      DependencyProperty.RegisterAttached("Fill", typeof(Brush), typeof(ButtonProperties), new PropertyMetadata(null));

      }


      Generic.xaml -- BaseButtonStyle



        <Style x:Key="BaseButtonStyle" TargetType="{x:Type ToggleButton}">
      <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Blue"/>
      <Setter Property="Template">
      <Setter.Value>
      <ControlTemplate TargetType="{x:Type ToggleButton}">
      <Grid>
      <TextBlock Text="Some Text">
      <TextBlock.Foreground>
      <SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.MyForegroundColor)}" />
      </TextBlock.Foreground>
      </TextBlock>

      <Path x:Name="path1" Data="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.Data)}"
      Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.Fill)}"
      Stroke="Black"/>

      <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True"
      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
      </Grid>
      <ControlTemplate.Triggers>
      <Trigger Property="IsMouseOver" Value="true">
      <Setter TargetName="path1" Property = "Opacity" Value="0.4"/>
      </Trigger>
      <Trigger Property="IsChecked" Value="true">
      <Trigger.EnterActions>
      <BeginStoryboard Storyboard="{StaticResource Blink_On}"/>
      </Trigger.EnterActions>
      <Trigger.ExitActions>
      <BeginStoryboard Storyboard="{StaticResource Blink_Off}"/>
      </Trigger.ExitActions>
      </Trigger>
      </ControlTemplate.Triggers>
      </ControlTemplate>
      </Setter.Value>
      </Setter>
      </Style>


      Generic.xaml -- ModifiedButtonStyle1



       <Style x:Key="ModifiedButtonStyle1" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}">
      <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Red" />
      <Setter Property="local:ButtonProperties.Data" Value="{StaticResource Arc0}" />
      <Setter Property="local:ButtonProperties.Fill" Value="LightGreen"/>
      </Style>
      <Style x:Key="ModifiedButtonStyle2" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}">
      <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Red" />
      <Setter Property="local:ButtonProperties.Data" Value="{StaticResource Arc45}" />
      <Setter Property="local:ButtonProperties.Fill" Value="LightPink"/>
      </Style>
      <Style x:Key="ModifiedButtonStyle3" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}">
      <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Red" />
      <Setter Property="local:ButtonProperties.Data" Value="{StaticResource Arc90}" />
      <Setter Property="local:ButtonProperties.Fill" Value="LightCoral"/>
      </Style>


      Generic.xaml -- Using the ModifiedButtonStyles in a custom control, RingControl



       <Style TargetType="{x:Type local:RingButtons2}">
      <Setter Property="Template">
      <Setter.Value>
      <ControlTemplate TargetType="{x:Type local:RingButtons2}">
      <Border Background="{TemplateBinding Background}"
      BorderBrush="{TemplateBinding BorderBrush}"
      BorderThickness="{TemplateBinding BorderThickness}">

      <Viewbox>
      <Grid>
      <!--Outer Rim -->
      <Path Data="{StaticResource OuterRim}" Fill="Silver" Stroke="Black" />
      <Path Data="{StaticResource OuterWheelBackground}" Fill="White" Stroke="Black" />

      <ToggleButton x:Name="PART_Button1" Style="{StaticResource ModifiedButtonStyle1}"/>
      <ToggleButton x:Name="PART_Button2" Style="{StaticResource ModifiedButtonStyle2}"/>
      <ToggleButton x:Name="PART_Button3" Style="{StaticResource ModifiedButtonStyle3}"/>
      ........................................................
      </Grid>
      </Viewbox>
      </Border>
      </ControlTemplate>
      </Setter.Value>
      </Setter>
      </Style>


      Using the RingControl2 in the user interface:



             <w:RingButtons2/>


      It would appear that clicking anywhere in the RingButtons2 control results only in the first defined togglebutton responding -- not any of the others.



      How can I fix this so that each of the togglebuttons acts independently of the others and respects its own controltemplate triggers?



      Thanks again.



      Edit#2



      Upon removing the TextBlock definition from the BaseButtonStyle,



       <TextBlock Text="Some Text">
      <TextBlock.Foreground>
      <SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.MyForegroundColor)}" />
      </TextBlock.Foreground>
      </TextBlock>


      ALL WORKS! Why is this??



      Thanks.







      wpf generic.xaml






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 31 '18 at 4:19







      Alan Wayne

















      asked Dec 30 '18 at 5:16









      Alan WayneAlan Wayne

      1,63122251




      1,63122251
























          1 Answer
          1






          active

          oldest

          votes


















          2














          If the target control has dependency properties that you can use for those custom bindings then you can use TemplateBinding, here's an example:



              <Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}">
          <Setter Property="Foreground" Value="Blue" />
          <Setter Property="Template">
          <Setter.Value>
          <ControlTemplate TargetType="{x:Type Button}">
          <TextBlock Text="Some Text" Foreground="{TemplateBinding Foreground}" />
          </ControlTemplate>
          </Setter.Value>
          </Setter>
          </Style>

          <Style x:Key="ModifiedButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}">
          <Setter Property="Foreground" Value="Red" />
          </Style>


          Which you would then refer to like so:



          <Grid>
          <Button Style="{StaticResource ModifiedButtonStyle}" />
          </Grid>


          However, in the example you've given above you're using a Path and a Fill inside a template, which I'm guessing don't have associated properties. In this case your options are to either create a new control and add those properties to it or, preferably, use attached properties. In the case of the latter you'd create an attached property like this:



          public static class ButtonProperties
          {
          public static Color GetMyForegroundColor(DependencyObject obj)
          {
          return (Color)obj.GetValue(MyForegroundColorProperty);
          }

          public static void SetMyForegroundColor(DependencyObject obj, Color value)
          {
          obj.SetValue(MyForegroundColorProperty, value);
          }

          // Using a DependencyProperty as the backing store for MyForegroundColor. This enables animation, styling, binding, etc...
          public static readonly DependencyProperty MyForegroundColorProperty =
          DependencyProperty.RegisterAttached("MyForegroundColor", typeof(Color), typeof(ButtonProperties), new PropertyMetadata(Colors.Black));
          }


          And then you'd reference and override it like this in your XAML:



          <Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}">
          <Setter Property="behaviors:ButtonProperties.MyForegroundColor" Value="Blue"/>
          <Setter Property="Template">
          <Setter.Value>
          <ControlTemplate TargetType="{x:Type Button}">
          <TextBlock Text="Some Text">
          <TextBlock.Foreground>
          <SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent},
          Path=(behaviors:ButtonProperties.MyForegroundColor)}" />
          </TextBlock.Foreground>
          </TextBlock>
          </ControlTemplate>
          </Setter.Value>
          </Setter>
          </Style>

          <Style x:Key="ModifiedButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}">
          <Setter Property="behaviors:ButtonProperties.MyForegroundColor" Value="Red" />
          </Style>


          These are more-or-less the same, it's just that in the first case you're using existing properties already inside the control (or creating a new control that has them) whereas in the second case you're declaring and attaching them to an existing control externally.






          share|improve this answer


























          • It looks very promising, but I will need some sleep before checking this. Thanks. :)

            – Alan Wayne
            Dec 30 '18 at 6:32






          • 1





            Excellent! The syntax is completely new to me, but works perfectly. Thank you much!

            – Alan Wayne
            Dec 30 '18 at 20:08











          • Actually you've probably been using them all along without realizing. Whenever you add something like Grid.Row="0" to a control...that isn't an internal property that every WPF control supports, it's an attached property that the Grid class creates and references (when present) during the layout process.

            – Mark Feldman
            Dec 30 '18 at 21:09











          • Sorry...Upon further work, the Data and Fill properties work correctly for each ModifiedButtonStyle. However, the controltemplate triggers only seem to work for the first defined button--no other button seems to respond visually to the triggers. Any suggestions?? Thanks. (Please see Edit#1).

            – Alan Wayne
            Dec 31 '18 at 4:04













          • Upon removing the TextBlock element from the BaseButtonStyle, the controltemplate triggers now work correctly for each button...Why??? Thanks. :)

            – Alan Wayne
            Dec 31 '18 at 4:21











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53975433%2fhow-to-use-basedon-to-template-a-toggle-button-in-generic-xaml%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          If the target control has dependency properties that you can use for those custom bindings then you can use TemplateBinding, here's an example:



              <Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}">
          <Setter Property="Foreground" Value="Blue" />
          <Setter Property="Template">
          <Setter.Value>
          <ControlTemplate TargetType="{x:Type Button}">
          <TextBlock Text="Some Text" Foreground="{TemplateBinding Foreground}" />
          </ControlTemplate>
          </Setter.Value>
          </Setter>
          </Style>

          <Style x:Key="ModifiedButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}">
          <Setter Property="Foreground" Value="Red" />
          </Style>


          Which you would then refer to like so:



          <Grid>
          <Button Style="{StaticResource ModifiedButtonStyle}" />
          </Grid>


          However, in the example you've given above you're using a Path and a Fill inside a template, which I'm guessing don't have associated properties. In this case your options are to either create a new control and add those properties to it or, preferably, use attached properties. In the case of the latter you'd create an attached property like this:



          public static class ButtonProperties
          {
          public static Color GetMyForegroundColor(DependencyObject obj)
          {
          return (Color)obj.GetValue(MyForegroundColorProperty);
          }

          public static void SetMyForegroundColor(DependencyObject obj, Color value)
          {
          obj.SetValue(MyForegroundColorProperty, value);
          }

          // Using a DependencyProperty as the backing store for MyForegroundColor. This enables animation, styling, binding, etc...
          public static readonly DependencyProperty MyForegroundColorProperty =
          DependencyProperty.RegisterAttached("MyForegroundColor", typeof(Color), typeof(ButtonProperties), new PropertyMetadata(Colors.Black));
          }


          And then you'd reference and override it like this in your XAML:



          <Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}">
          <Setter Property="behaviors:ButtonProperties.MyForegroundColor" Value="Blue"/>
          <Setter Property="Template">
          <Setter.Value>
          <ControlTemplate TargetType="{x:Type Button}">
          <TextBlock Text="Some Text">
          <TextBlock.Foreground>
          <SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent},
          Path=(behaviors:ButtonProperties.MyForegroundColor)}" />
          </TextBlock.Foreground>
          </TextBlock>
          </ControlTemplate>
          </Setter.Value>
          </Setter>
          </Style>

          <Style x:Key="ModifiedButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}">
          <Setter Property="behaviors:ButtonProperties.MyForegroundColor" Value="Red" />
          </Style>


          These are more-or-less the same, it's just that in the first case you're using existing properties already inside the control (or creating a new control that has them) whereas in the second case you're declaring and attaching them to an existing control externally.






          share|improve this answer


























          • It looks very promising, but I will need some sleep before checking this. Thanks. :)

            – Alan Wayne
            Dec 30 '18 at 6:32






          • 1





            Excellent! The syntax is completely new to me, but works perfectly. Thank you much!

            – Alan Wayne
            Dec 30 '18 at 20:08











          • Actually you've probably been using them all along without realizing. Whenever you add something like Grid.Row="0" to a control...that isn't an internal property that every WPF control supports, it's an attached property that the Grid class creates and references (when present) during the layout process.

            – Mark Feldman
            Dec 30 '18 at 21:09











          • Sorry...Upon further work, the Data and Fill properties work correctly for each ModifiedButtonStyle. However, the controltemplate triggers only seem to work for the first defined button--no other button seems to respond visually to the triggers. Any suggestions?? Thanks. (Please see Edit#1).

            – Alan Wayne
            Dec 31 '18 at 4:04













          • Upon removing the TextBlock element from the BaseButtonStyle, the controltemplate triggers now work correctly for each button...Why??? Thanks. :)

            – Alan Wayne
            Dec 31 '18 at 4:21
















          2














          If the target control has dependency properties that you can use for those custom bindings then you can use TemplateBinding, here's an example:



              <Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}">
          <Setter Property="Foreground" Value="Blue" />
          <Setter Property="Template">
          <Setter.Value>
          <ControlTemplate TargetType="{x:Type Button}">
          <TextBlock Text="Some Text" Foreground="{TemplateBinding Foreground}" />
          </ControlTemplate>
          </Setter.Value>
          </Setter>
          </Style>

          <Style x:Key="ModifiedButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}">
          <Setter Property="Foreground" Value="Red" />
          </Style>


          Which you would then refer to like so:



          <Grid>
          <Button Style="{StaticResource ModifiedButtonStyle}" />
          </Grid>


          However, in the example you've given above you're using a Path and a Fill inside a template, which I'm guessing don't have associated properties. In this case your options are to either create a new control and add those properties to it or, preferably, use attached properties. In the case of the latter you'd create an attached property like this:



          public static class ButtonProperties
          {
          public static Color GetMyForegroundColor(DependencyObject obj)
          {
          return (Color)obj.GetValue(MyForegroundColorProperty);
          }

          public static void SetMyForegroundColor(DependencyObject obj, Color value)
          {
          obj.SetValue(MyForegroundColorProperty, value);
          }

          // Using a DependencyProperty as the backing store for MyForegroundColor. This enables animation, styling, binding, etc...
          public static readonly DependencyProperty MyForegroundColorProperty =
          DependencyProperty.RegisterAttached("MyForegroundColor", typeof(Color), typeof(ButtonProperties), new PropertyMetadata(Colors.Black));
          }


          And then you'd reference and override it like this in your XAML:



          <Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}">
          <Setter Property="behaviors:ButtonProperties.MyForegroundColor" Value="Blue"/>
          <Setter Property="Template">
          <Setter.Value>
          <ControlTemplate TargetType="{x:Type Button}">
          <TextBlock Text="Some Text">
          <TextBlock.Foreground>
          <SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent},
          Path=(behaviors:ButtonProperties.MyForegroundColor)}" />
          </TextBlock.Foreground>
          </TextBlock>
          </ControlTemplate>
          </Setter.Value>
          </Setter>
          </Style>

          <Style x:Key="ModifiedButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}">
          <Setter Property="behaviors:ButtonProperties.MyForegroundColor" Value="Red" />
          </Style>


          These are more-or-less the same, it's just that in the first case you're using existing properties already inside the control (or creating a new control that has them) whereas in the second case you're declaring and attaching them to an existing control externally.






          share|improve this answer


























          • It looks very promising, but I will need some sleep before checking this. Thanks. :)

            – Alan Wayne
            Dec 30 '18 at 6:32






          • 1





            Excellent! The syntax is completely new to me, but works perfectly. Thank you much!

            – Alan Wayne
            Dec 30 '18 at 20:08











          • Actually you've probably been using them all along without realizing. Whenever you add something like Grid.Row="0" to a control...that isn't an internal property that every WPF control supports, it's an attached property that the Grid class creates and references (when present) during the layout process.

            – Mark Feldman
            Dec 30 '18 at 21:09











          • Sorry...Upon further work, the Data and Fill properties work correctly for each ModifiedButtonStyle. However, the controltemplate triggers only seem to work for the first defined button--no other button seems to respond visually to the triggers. Any suggestions?? Thanks. (Please see Edit#1).

            – Alan Wayne
            Dec 31 '18 at 4:04













          • Upon removing the TextBlock element from the BaseButtonStyle, the controltemplate triggers now work correctly for each button...Why??? Thanks. :)

            – Alan Wayne
            Dec 31 '18 at 4:21














          2












          2








          2







          If the target control has dependency properties that you can use for those custom bindings then you can use TemplateBinding, here's an example:



              <Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}">
          <Setter Property="Foreground" Value="Blue" />
          <Setter Property="Template">
          <Setter.Value>
          <ControlTemplate TargetType="{x:Type Button}">
          <TextBlock Text="Some Text" Foreground="{TemplateBinding Foreground}" />
          </ControlTemplate>
          </Setter.Value>
          </Setter>
          </Style>

          <Style x:Key="ModifiedButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}">
          <Setter Property="Foreground" Value="Red" />
          </Style>


          Which you would then refer to like so:



          <Grid>
          <Button Style="{StaticResource ModifiedButtonStyle}" />
          </Grid>


          However, in the example you've given above you're using a Path and a Fill inside a template, which I'm guessing don't have associated properties. In this case your options are to either create a new control and add those properties to it or, preferably, use attached properties. In the case of the latter you'd create an attached property like this:



          public static class ButtonProperties
          {
          public static Color GetMyForegroundColor(DependencyObject obj)
          {
          return (Color)obj.GetValue(MyForegroundColorProperty);
          }

          public static void SetMyForegroundColor(DependencyObject obj, Color value)
          {
          obj.SetValue(MyForegroundColorProperty, value);
          }

          // Using a DependencyProperty as the backing store for MyForegroundColor. This enables animation, styling, binding, etc...
          public static readonly DependencyProperty MyForegroundColorProperty =
          DependencyProperty.RegisterAttached("MyForegroundColor", typeof(Color), typeof(ButtonProperties), new PropertyMetadata(Colors.Black));
          }


          And then you'd reference and override it like this in your XAML:



          <Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}">
          <Setter Property="behaviors:ButtonProperties.MyForegroundColor" Value="Blue"/>
          <Setter Property="Template">
          <Setter.Value>
          <ControlTemplate TargetType="{x:Type Button}">
          <TextBlock Text="Some Text">
          <TextBlock.Foreground>
          <SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent},
          Path=(behaviors:ButtonProperties.MyForegroundColor)}" />
          </TextBlock.Foreground>
          </TextBlock>
          </ControlTemplate>
          </Setter.Value>
          </Setter>
          </Style>

          <Style x:Key="ModifiedButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}">
          <Setter Property="behaviors:ButtonProperties.MyForegroundColor" Value="Red" />
          </Style>


          These are more-or-less the same, it's just that in the first case you're using existing properties already inside the control (or creating a new control that has them) whereas in the second case you're declaring and attaching them to an existing control externally.






          share|improve this answer















          If the target control has dependency properties that you can use for those custom bindings then you can use TemplateBinding, here's an example:



              <Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}">
          <Setter Property="Foreground" Value="Blue" />
          <Setter Property="Template">
          <Setter.Value>
          <ControlTemplate TargetType="{x:Type Button}">
          <TextBlock Text="Some Text" Foreground="{TemplateBinding Foreground}" />
          </ControlTemplate>
          </Setter.Value>
          </Setter>
          </Style>

          <Style x:Key="ModifiedButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}">
          <Setter Property="Foreground" Value="Red" />
          </Style>


          Which you would then refer to like so:



          <Grid>
          <Button Style="{StaticResource ModifiedButtonStyle}" />
          </Grid>


          However, in the example you've given above you're using a Path and a Fill inside a template, which I'm guessing don't have associated properties. In this case your options are to either create a new control and add those properties to it or, preferably, use attached properties. In the case of the latter you'd create an attached property like this:



          public static class ButtonProperties
          {
          public static Color GetMyForegroundColor(DependencyObject obj)
          {
          return (Color)obj.GetValue(MyForegroundColorProperty);
          }

          public static void SetMyForegroundColor(DependencyObject obj, Color value)
          {
          obj.SetValue(MyForegroundColorProperty, value);
          }

          // Using a DependencyProperty as the backing store for MyForegroundColor. This enables animation, styling, binding, etc...
          public static readonly DependencyProperty MyForegroundColorProperty =
          DependencyProperty.RegisterAttached("MyForegroundColor", typeof(Color), typeof(ButtonProperties), new PropertyMetadata(Colors.Black));
          }


          And then you'd reference and override it like this in your XAML:



          <Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}">
          <Setter Property="behaviors:ButtonProperties.MyForegroundColor" Value="Blue"/>
          <Setter Property="Template">
          <Setter.Value>
          <ControlTemplate TargetType="{x:Type Button}">
          <TextBlock Text="Some Text">
          <TextBlock.Foreground>
          <SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent},
          Path=(behaviors:ButtonProperties.MyForegroundColor)}" />
          </TextBlock.Foreground>
          </TextBlock>
          </ControlTemplate>
          </Setter.Value>
          </Setter>
          </Style>

          <Style x:Key="ModifiedButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}">
          <Setter Property="behaviors:ButtonProperties.MyForegroundColor" Value="Red" />
          </Style>


          These are more-or-less the same, it's just that in the first case you're using existing properties already inside the control (or creating a new control that has them) whereas in the second case you're declaring and attaching them to an existing control externally.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Dec 30 '18 at 6:27

























          answered Dec 30 '18 at 6:18









          Mark FeldmanMark Feldman

          8,51311738




          8,51311738













          • It looks very promising, but I will need some sleep before checking this. Thanks. :)

            – Alan Wayne
            Dec 30 '18 at 6:32






          • 1





            Excellent! The syntax is completely new to me, but works perfectly. Thank you much!

            – Alan Wayne
            Dec 30 '18 at 20:08











          • Actually you've probably been using them all along without realizing. Whenever you add something like Grid.Row="0" to a control...that isn't an internal property that every WPF control supports, it's an attached property that the Grid class creates and references (when present) during the layout process.

            – Mark Feldman
            Dec 30 '18 at 21:09











          • Sorry...Upon further work, the Data and Fill properties work correctly for each ModifiedButtonStyle. However, the controltemplate triggers only seem to work for the first defined button--no other button seems to respond visually to the triggers. Any suggestions?? Thanks. (Please see Edit#1).

            – Alan Wayne
            Dec 31 '18 at 4:04













          • Upon removing the TextBlock element from the BaseButtonStyle, the controltemplate triggers now work correctly for each button...Why??? Thanks. :)

            – Alan Wayne
            Dec 31 '18 at 4:21



















          • It looks very promising, but I will need some sleep before checking this. Thanks. :)

            – Alan Wayne
            Dec 30 '18 at 6:32






          • 1





            Excellent! The syntax is completely new to me, but works perfectly. Thank you much!

            – Alan Wayne
            Dec 30 '18 at 20:08











          • Actually you've probably been using them all along without realizing. Whenever you add something like Grid.Row="0" to a control...that isn't an internal property that every WPF control supports, it's an attached property that the Grid class creates and references (when present) during the layout process.

            – Mark Feldman
            Dec 30 '18 at 21:09











          • Sorry...Upon further work, the Data and Fill properties work correctly for each ModifiedButtonStyle. However, the controltemplate triggers only seem to work for the first defined button--no other button seems to respond visually to the triggers. Any suggestions?? Thanks. (Please see Edit#1).

            – Alan Wayne
            Dec 31 '18 at 4:04













          • Upon removing the TextBlock element from the BaseButtonStyle, the controltemplate triggers now work correctly for each button...Why??? Thanks. :)

            – Alan Wayne
            Dec 31 '18 at 4:21

















          It looks very promising, but I will need some sleep before checking this. Thanks. :)

          – Alan Wayne
          Dec 30 '18 at 6:32





          It looks very promising, but I will need some sleep before checking this. Thanks. :)

          – Alan Wayne
          Dec 30 '18 at 6:32




          1




          1





          Excellent! The syntax is completely new to me, but works perfectly. Thank you much!

          – Alan Wayne
          Dec 30 '18 at 20:08





          Excellent! The syntax is completely new to me, but works perfectly. Thank you much!

          – Alan Wayne
          Dec 30 '18 at 20:08













          Actually you've probably been using them all along without realizing. Whenever you add something like Grid.Row="0" to a control...that isn't an internal property that every WPF control supports, it's an attached property that the Grid class creates and references (when present) during the layout process.

          – Mark Feldman
          Dec 30 '18 at 21:09





          Actually you've probably been using them all along without realizing. Whenever you add something like Grid.Row="0" to a control...that isn't an internal property that every WPF control supports, it's an attached property that the Grid class creates and references (when present) during the layout process.

          – Mark Feldman
          Dec 30 '18 at 21:09













          Sorry...Upon further work, the Data and Fill properties work correctly for each ModifiedButtonStyle. However, the controltemplate triggers only seem to work for the first defined button--no other button seems to respond visually to the triggers. Any suggestions?? Thanks. (Please see Edit#1).

          – Alan Wayne
          Dec 31 '18 at 4:04







          Sorry...Upon further work, the Data and Fill properties work correctly for each ModifiedButtonStyle. However, the controltemplate triggers only seem to work for the first defined button--no other button seems to respond visually to the triggers. Any suggestions?? Thanks. (Please see Edit#1).

          – Alan Wayne
          Dec 31 '18 at 4:04















          Upon removing the TextBlock element from the BaseButtonStyle, the controltemplate triggers now work correctly for each button...Why??? Thanks. :)

          – Alan Wayne
          Dec 31 '18 at 4:21





          Upon removing the TextBlock element from the BaseButtonStyle, the controltemplate triggers now work correctly for each button...Why??? Thanks. :)

          – Alan Wayne
          Dec 31 '18 at 4:21


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53975433%2fhow-to-use-basedon-to-template-a-toggle-button-in-generic-xaml%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Monofisismo

          Angular Downloading a file using contenturl with Basic Authentication

          Olmecas