изменение цвета фона контейнера, когда текстовое поле находится в фокусе - PullRequest
2 голосов
/ 18 сентября 2009

У меня есть простой пользовательский элемент управления с TextBox. Я хочу изменить цвет пользовательского элемента управления, когда TextBox получает фокус. Вот что у меня есть:

<UserControl x:Class="OutLookContactList.ContactSearchControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="root" MinHeight="30" Loaded="UserControl_Loaded">

<UserControl.Resources>

    <Style x:Key="searchTextBoxStyle" TargetType="{x:Type TextBox}">
        <Style.Triggers>
            <Trigger Property="IsFocused" Value="true">
                <Setter TargetName="root" Property="Background" Value="{StaticResource OnMouseOverColor}" />
            </Trigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>

Но я получаю сообщение об ошибке «Свойство TargetName не может быть установлено в Setter стиля». Как установить цвет фона пользовательского элемента управления, когда текстовое поле получает фокус? Спасибо большое

Ответы [ 3 ]

9 голосов
/ 18 сентября 2009

Будет ли работать, чтобы обернуть содержимое вашего UserControl в Border объект? Если это так, вы можете просто оформить Border так:

<UserControl x:Class="Sample2.ContactSearchControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="75" Width="300">
    <Border>
        <Border.Style>
            <Style TargetType="Border">
                <Setter Property="Background" Value="White" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsFocused, ElementName=txtSearch}" Value="true">
                        <Setter Property="Background" Value="Black" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Border.Style>
        <StackPanel>
            <TextBox x:Name="txtSearch" Text="Search" />
            <TextBox Text="Other" />
        </StackPanel>
    </Border>
</UserControl>

Обновление: (отвечая на вопросы Шераза)

Я не уверен, почему ElementName не работает для доступа к детям в UserControl. Это может быть связано с тем, как построено визуальное дерево.

Что касается Trigger против DataTrigger: Триггер - для свойств зависимости, а DataTrigger - для свойств с привязкой к данным (данные или другие элементы управления). Поскольку вы пытаетесь стилизовать Border, имеет смысл поместить туда DataTrigger и заставить его смотреть TextBox, чем TextBox изменить внешний вид Border.

Насколько я понимаю, свойство TargetName Setter применимо только в пределах DataTemplate или ControlTemplate. ( Информация от доктора WPF в этом сообщении на форуме )

2 голосов
/ 18 сентября 2009

Вот некоторый XAML, который работает в Kaxaml :

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

  <Page.Style>
    <Style TargetType="Page">
      <Setter Property="Background" Value="#CCCCD0" />
      <Style.Triggers>
        <DataTrigger Binding="{Binding ElementName=txtSearch, Path=IsFocused}"
                     Value="true">
          <Setter Property="Background" Value="Black" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </Page.Style>

  <TextBox x:Name="txtSearch" Width="100"
           HorizontalAlignment="Center" VerticalAlignment="Center" />

</Page>

Вы бы изменили объект Page на свой UserControl. Я считаю, что гораздо проще протестировать подобные вещи в инструменте быстрого прототипирования, таком как Kaxaml, прежде чем кодировать UserControl в VS.

Обратите внимание, что вы должны установить цвет по умолчанию (в данном случае #CCCCD0) с помощью установщика свойств, а не с помощью атрибута на самом Page. Это связано с тем, что атрибут переопределяет значение, установленное триггером (потому что это триггер стиля), поэтому, даже если триггер сработает, он всегда будет перегружен спецификацией локального атрибута, то есть он не изменится. Я только указываю на это, потому что это довольно распространенная ошибка.

2 голосов
/ 18 сентября 2009

Если вы меняли фон текстового поля, вам нужно удалить свойство TargetName:

<Style x:Key="searchTextBoxStyle" TargetType="{x:Type TextBox}">
    <Style.Triggers>
        <Trigger Property="IsFocused" Value="true">
            <Setter Property="Background" Value="{StaticResource OnMouseOverColor}" />
        </Trigger>
    </Style.Triggers>
</Style>

и измените TextBox, который хочет, чтобы этот стиль был:

<TextBox Style="{StaticResource searchTextBoxStyle}" .... />

Однако, поскольку вы хотите изменить значение родительского пользовательского элемента управления, это не даст вам желаемого.

Конечно, вы можете сделать это в коде, добавив обработчик события GotFocus и поместив код для изменения цвета фона.

...