Изменение цвета смещения линейного градиента шаблона содержимого на основе цвета фона привязки шаблона WPF

Хорошо, вот в чем проблема. Я пытаюсь выяснить, как сделать эту работу:

Рассмотрим следующий шаблон ControlTemplate для создания пользовательской кнопки:

<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>
<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>

Хорошо, теперь главный вопрос этот..

Вопрос 1: Почему строка, помеченная комментарием об ошибке в ControlTemplate кнопки, НЕ получает фоновый цвет, используя привязку шаблона? Если бы я использовал сплошной цвет, он бы работал нормально, поэтому я не вижу причин, почему он не должен работать таким образом. И, пожалуйста, укажите причину, по которой это происходит.

Ниже все еще немного неясно, и я не знаю, могут ли они быть связаны с проблемой, если кто-то может их устранить, это было бы здорово.

Вопрос 2: В чем разница между этими двумя значениями TargetType "Button" и "{x:Type Button}". Я знаю, что они эквивалентны typeof, но есть ли разница между ними? Я читал MSDN, но реальная разница не так очевидна.

Вопрос 3: Когда я буду использовать x:Name и когда я буду использовать Name? Разница опять неясна.

Вопрос 4: Что делает x:Static?

1 ответ

Я думаю, что ваш шаблон не работает правильно, потому что свойство Background является Brush (класс). И вы пытаетесь связать его с цветом (структура)

UPD Вы можете использовать простой конвертер вот так:

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();
    }
}

Добавьте это к ресурсам:

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

И измените свой стиль:

 <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>

Или вы можете использовать привязку следующим образом (если вы уверены, что Background - SolidColorBrush):

<GradientStop Color="{Binding Path=Background.Color, RelativeSource={RelativeSource TemplatedParent}}" Offset="0.5"/>
Другие вопросы по тегам