0
votes

Ok so here's the problem. Am trying to figure out how to make this work:

Consider the following ControlTemplate for creating a Custom Button:

<ControlTemplate x:Key ="cButton" TargetType="{x:Type Button}">
      <!--Styles-->
      <Grid x:Name="bkg">
      <Grid.Background>
         <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
           <GradientStop Color="{TemplateBinding Background}" Offset="0.5"/><!-- Error! -->
           <GradientStop Color="White" Offset="1.0"/>
       </LinearGradientBrush>
      </Grid.Background>
      <ContentPresenter 
    TextBlock.FontSize="80" 
    HorizontalAlignment="Center" 
    VerticalAlignment="Center" 
    ContentSource="Content" />
      </Grid>
      <!--Triggers-->
      <ControlTemplate.Triggers>
         <Trigger Property="IsPressed" Value="True">
         <Setter TargetName="bkg" Property="Background" Value="White"/>
         </Trigger>
      </ControlTemplate.Triggers>
   </ControlTemplate>

This Control Template forms part of this script and as you can see I am trying to get the background colour from the button declaration outlined in the main grid.

<Grid>
<Grid.Resources>
   <ControlTemplate x:Key ="cButton" TargetType="{x:Type Button}">
      <!--Styles-->
      <Grid x:Name="bkg">
      <Grid.Background>
         <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
           <GradientStop Color="{TemplateBinding Background}" Offset="0.5"/><!-- Error! -->
           <GradientStop Color="White" Offset="1.0"/>
       </LinearGradientBrush>
      </Grid.Background>
      <ContentPresenter 
    TextBlock.FontSize="80" 
    HorizontalAlignment="Center" 
    VerticalAlignment="Center" 
    ContentSource="Content" />
      </Grid>
      <!--Triggers-->
      <ControlTemplate.Triggers>
         <Trigger Property="IsPressed" Value="True">
         <Setter TargetName="bkg" Property="Background" Value="White"/>
         </Trigger>
      </ControlTemplate.Triggers>
   </ControlTemplate>
  </Grid.Resources>
  <Grid.ColumnDefinitions>
   <ColumnDefinition Width="*"/>
    <ColumnDefinition Width="*"/>
  </Grid.ColumnDefinitions >
  <Button Name="btnIn" Grid.Column="0" Content="IN" Background="Green"  Foreground="White" Template="{StaticResource cButton}"/>
  <Button Name="btnOut" Grid.Column="1" Content="OUT" Background="Red" Foreground="White" Template="{StaticResource cButton}" />
  </Grid>

Ok now Main question is this one..

Question 1: Why is the line marked with an Error Comment in the ControlTemplate of the button NOT retrieving the background colour using the templatebinding? Had I used a solid colour it would have worked fine so I see no reason why it should not work in this manner. And please provide reason why this is happening.

The following are still a bit unclear and I don't know if they may be related to the problem, if someone can clear them out it would be great.

Question 2: What is the difference between these two TargetType values "Button" and "{x:Type Button}". I know that they are a typeof equivalent but is there any difference between the two? I read MSDN but the real difference is not that clear.

Question 3: When would I use x:Name and when would I use Name ? The difference again is unclear.

Question 4: What does x:Static do?

1
MANY THANKS hameleon86- So in summary for other readers - x:Type is a markup extension and when used within other markup extensions, the former one (which can be used as a property/value attribute within the element) would cause confusion as it might refer to a key rather than the type. x:Name can be accessed from everywhere and can access anything whereas Name can be used within FrameworkElement scope. x:Static for data transfer from constants in code behind to XAMLFalco

1 Answers

0
votes

I think that your template does not work correctly because Background property is a Brush (class). And you try bind it to Color (struct)

UPD You can use simple converter like this:

public class BrushToColorConverter: IValueConverter{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        SolidColorBrush b = value as SolidColorBrush;
        if (b != null)
        {
            return b.Color;
        }
        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Add it to resources:

<wpfApplication1:BrushToColorConverter x:Key="btcConv"/>

And modify your style:

 <Grid.Background>
                    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                        <GradientStop Color="{Binding Path=Background, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource btcConv}}" Offset="0.5"/>
                        <GradientStop Color="White" Offset="1.0"/>
                    </LinearGradientBrush>
                </Grid.Background>

Or you can use binding like this (if you sure that Background is SolidColorBrush):

<GradientStop Color="{Binding Path=Background.Color, RelativeSource={RelativeSource TemplatedParent}}" Offset="0.5"/>