changing background color of container when textbo

2019-05-24 13:12发布

I have a simple user control with a TextBox. I want to change the color of user control when the TextBox gets the focus. This is what I have:

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

But I get the errot "TargetName property cannot be set on a style Setter". How can I Set the back ground color of user control when text box gets the focus? Thanks a bunch

3条回答
爷的心禁止访问
2楼-- · 2019-05-24 13:16

Here's some XAML that works in 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>

You would change the Page object with your UserControl. I find it much easier to test these sorts of things out in a rapid prototyping tool such as Kaxaml before coding up the UserControl in VS.

Note that you have to set the default colour (in this case #CCCCD0) via a property setter and not via an attribute on the Page itself. This is because the attribute would override the value set by the trigger (because it's a style trigger), so even though the trigger would fire, it would always be trumpted by the local attribute specification, meaning that it wouldn't change. I only point this out because it's a fairly common gotcha.

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-05-24 13:26

If you were changing the background of the text box you need to remove the TargetName property:

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

and change the TextBox that wants this style to be:

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

However, as you want to change the value of the parent user control this won't give you want you want.

You could certainly do it in the code behind by adding a GotFocus event handler and putting the code to change the background colour in there.

查看更多
beautiful°
4楼-- · 2019-05-24 13:37

Will it work to wrap the contents of your UserControl inside a Border object? If so, you can simply style the Border like so:

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

Update: (Answering Sheraz' Questions)

I'm not sure why ElementName doesn't work for accessing children within a UserControl. It might have something to do with the way the visual tree is constructed.

As for Trigger vs DataTrigger: Trigger is for dependency properties and DataTrigger is for databound properties (data or other controls). Since you are trying to style the Border, it makes more sense to place the DataTrigger there and have it watch the TextBox than to have the TextBox change the appearance of the Border.

As I understand it, the TargetName property of Setter is only applicable within a DataTemplate or ControlTemplate. (Info from Dr. WPF in this forum post)

查看更多
登录 后发表回答