Возникла проблема с моим шаблоном управления TextBox - PullRequest
2 голосов
/ 20 февраля 2010

Я работаю над простым шаблоном textBox, который состоит из двух границ, одна с градиентным фоном. Теперь моя конкретная проблема заключается в том, что я хочу иметь возможность установить цвет переднего плана textBox на любой цвет, который я хочу, и чтобы он работал правильно. Тем не менее, я не могу заставить оба цвета переднего плана и цвета переднего плана работать вместе. Если я установлю красный цвет переднего плана, например, когда я отключу textBox, передний план не изменится на мой отключенный цвет. Я попытался привязать передний план в триггере IsEnabled = "true", но это не сработало. Передний план всегда остается красным, независимо от того, включен текстовый блок или нет.

Можете ли вы взглянуть на шаблон ниже и скажите, что я делаю не так? Также, пожалуйста, укажите мне на любые другие ошибки, которые я мог совершить, поскольку я новичок в создании шаблонов.

Большое спасибо.

  <SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />
  <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE" />
  <SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" />
  <SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" />


<Style x:Key="TextBoxControlTemplate1" TargetType="{x:Type TextBox}">
  <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
  <Setter Property="AllowDrop" Value="true"/>
  <Setter Property="Background" Value="#00000000"/>
  <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
  <Setter Property="VerticalContentAlignment" Value="Stretch"/>
  <Setter Property="FontFamily" Value="Segoe UI"/>
  <Setter Property="FontSize" Value="12"/>
  <Setter Property="Padding" Value="8,5,3,3"/>
  <Setter Property="BorderThickness" Value="0"/>
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type TextBox}">
        <Grid>
          <Border BorderBrush="#FF000000" BorderThickness="2,2,2,2" CornerRadius="5,5,5,5" Padding="0,0,0,0" Width="Auto" Height="Auto" Background="#FF000000"/>
          <Border x:Name="Border" BorderBrush="#FFFFFFFF" BorderThickness="1,1,1,1" CornerRadius="5,5,5,5" Padding="0,0,0,0" Width="Auto" Height="Auto" Margin="2,2,2,2">
            <Border.Background>
              <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FF000000" Offset="0"/>
                <GradientStop Color="#FF4D4D4D" Offset="1"/>
              </LinearGradientBrush>
            </Border.Background>
          </Border>
          <ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
        </Grid>
        <ControlTemplate.Triggers>
          <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Background" Value="{DynamicResource DisabledBackgroundBrush}" TargetName="Border"/>
            <Setter Property="BorderBrush" Value="{DynamicResource DisabledBackgroundBrush}" TargetName="Border"/>
            <Setter Property="Foreground" Value="{DynamicResource DisabledForegroundBrush}"/>
          </Trigger>
          <Trigger Property="IsEnabled" Value="True">
            <Setter Property="Foreground" Value="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type TextBox}}}"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>


<TextBox Text="TEST" TextWrapping="Wrap" Canvas.Top="293.761" Canvas.Left="112" Style="{DynamicResource TextBoxControlTemplate1}" Height="28.724" Width="232.25" IsTabStop="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" IsEnabled="True" Foreground="#FFFF0000"/>

Ответы [ 3 ]

3 голосов
/ 20 февраля 2010

Здесь есть несколько разных проблем, которые работают против вас.Во-первых, вы устанавливаете конкретное значение Foreground для своего экземпляра элемента управления, который имеет более высокий приоритет, чем значения, установленные из Trigger s в вашем Style для свойств самого элемента управления.Это отличается от свойств, установленных для элементов внутри ControlTemplate, например «Граница».То, как вы используете Trigger s для установки свойств Border, иллюстрирует это.Обычно вы также хотели бы использовать TemplateBinding s, чтобы получить значения, установленные в вашем экземпляре элемента управления, как значения по умолчанию, например Background, которые в настоящее время игнорируются.

Для переключения между двумя значениями свойства в вашемСтилизованный элемент управления, как вы хотите сделать с Foreground, вы можете использовать Setter и Trigger в вашем Style для обеспечения значения по умолчанию и альтернативного значения.Это все еще может быть переопределено значением, установленным в экземпляре.Если вы хотите запретить экземпляры, переопределяющие Trigger, установите его как «Границу» Trigger, где вы устанавливаете значения для элементов внутри ControlTemplate.

Последнее изменение, которое я рекомендую, этопереключение на StaticResource для кистей, которые вы тянете в Style.В этом случае это, вероятно, не будет иметь значения, но в некоторых случаях стиль по умолчанию может быть извлечен в контекст, который не имеет никакой ссылки на окружающие ресурсы из файла, в котором он был объявлен. Использование Static гарантирует, что онбудет включать эти ресурсы независимо от того, где он будет использоваться.Вы можете не столкнуться с этим, но это хорошая привычка при настройке стилей / шаблонов, подобных этой.

Вот ваш код с этими улучшениями:

<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />
<SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE" />

<Style x:Key="TextBoxControlTemplate1" TargetType="{x:Type TextBox}">
    <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
    <Setter Property="AllowDrop" Value="true"/>
    <Setter Property="Background">
        <Setter.Value>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FF000000" Offset="0"/>
                <GradientStop Color="#FF4D4D4D" Offset="1"/>
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    <Setter Property="FontFamily" Value="Segoe UI"/>
    <Setter Property="FontSize" Value="12"/>
    <Setter Property="Padding" Value="8,5,3,3"/>
    <Setter Property="BorderThickness" Value="2"/>
    <Setter Property="BorderBrush" Value="#FF000000"/>
    <Setter Property="Foreground" Value="Red" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Grid>
                    <!--Take advantage of containment when possible to let the layout engine help you!-->
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="5" Padding="0" Background="#FF000000"/>
                    <Border x:Name="Border" BorderBrush="#FFFFFFFF" BorderThickness="1" CornerRadius="5" Padding="0" Margin="{TemplateBinding BorderThickness}"
                            Background="{TemplateBinding Background}"/>
                    <ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Background" Value="{StaticResource DisabledBackgroundBrush}" TargetName="Border"/>
                        <Setter Property="BorderBrush" Value="{StaticResource DisabledBackgroundBrush}" TargetName="Border"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
        </Trigger>
    </Style.Triggers>
</Style>

И TextBoxиспользуя только настройки Style:

<TextBox Text="TEST" TextWrapping="Wrap" Canvas.Top="293.761" Canvas.Left="112" Style="{DynamicResource TextBoxControlTemplate1}" 
         Height="28.724" Width="232.25" IsTabStop="False" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" />
1 голос
/ 20 февраля 2010

Возможная причина в том, что ваш DisabledBackgroundBrush не виден в том месте, где вы используете свой стиль.Пожалуйста, попробуйте добавить стили в ресурсы ControlTemplate:

<ControlTemplate TargetType="{x:Type TextBox}">
    <ControlTemplate.Resources>
        <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE" />
        ...
    </ControlTemplate.Resources>
    ...

Кстати, ваш шаблон управления не учитывает значения ваших свойств.Например, вам, возможно, следует использовать что-то вроде

<ScrollViewer Margin="{TemplateBinding Padding}" x:Name="PART_ContentHost"/>

в вашем шаблоне управления.

1 голос
/ 20 февраля 2010

Пара идей, чтобы попробовать:

  1. Избавьтесь от одного из ваших триггеров.Наличие двух противоположных триггеров не может быть хорошей идеей.Я бы установил значения по умолчанию Background, BorderBrush и Foreground непосредственно в вашей декларации Border и удалил триггер Enabled="True".Тогда отладка - это только вопрос правильного запуска триггера Enabled="False".

  2. Добавьте свойство TargetName в setter для триггера Enabled="False".

  3. Это длинный снимок, но используйте UIElement.IsEnabled вместо просто IsEnabled, например: <Trigger Property="UIElement.IsEnabled">.

Надеюсь, что то, что я здесь сказал, поможет!

...