wpf 当文本框处于焦点时更改容器的背景颜色

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1441059/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:00:50  来源:igfitidea点击:

changing background color of container when textbox is in focus

wpftextboxfocus

提问by Sheraz

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

我有一个简单的用户控件,带有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>

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

但是我得到了错误“无法在样式设置器上设置 TargetName 属性”。当文本框获得焦点时,如何设置用户控件的背景颜色?谢谢一堆

回答by Joseph Sturtevant

Will it work to wrap the contents of your UserControlinside a Borderobject? If so, you can simply style the Borderlike so:

将您的内容包装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>

Update: (Answering Sheraz' Questions)

更新:(回答 Sheraz 的问题)

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

我不确定为什么ElementName不能访问UserControl. 它可能与构建可视化树的方式有关。

As for Triggervs DataTrigger: Triggeris for dependency properties and DataTriggeris for databound properties (data orother controls). Since you are trying to style the Border, it makes more sense to place the DataTriggerthere and have it watch the TextBoxthan to have the TextBoxchange the appearance of the Border.

至于Triggervs DataTriggerTrigger用于依赖属性,DataTrigger用于数据绑定属性(数据其他控件)。既然你想的风格Border,它更有意义的地方在DataTrigger那里,有它观看TextBox比有TextBox变化的外观Border

As I understand it, the TargetNameproperty of Setteris only applicable within a DataTemplateor ControlTemplate. (Info from Dr. WPF in this forum post)

据我了解,TargetNameof的属性Setter仅适用于 aDataTemplateControlTemplate。(此论坛帖子中来自 WPF 博士的信息

回答by ChrisF

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

如果您要更改文本框的背景,则需要删除该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>

and change the TextBox that wants this style to be:

并将想要此样式的 TextBox 更改为:

<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 GotFocusevent handler and putting the code to change the background colour in there.

您当然可以通过添加GotFocus事件处理程序并在其中放置更改背景颜色的代码在后面的代码中执行此操作。

回答by Drew Noakes

Here's some XAML that works in Kaxaml:

下面是一些适用于Kaxaml 的XAML :

<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 Pageobject 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 UserControlin VS.

你会Page用你的UserControl. 我发现UserControl在 VS 中编码之前,在快速原型设计工具(如 Kaxaml)中测试这些东西要容易得多。

Note that you have to set the default colour (in this case #CCCCD0) via a property setter and not via an attribute on the Pageitself. 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.

请注意,您必须#CCCCD0通过属性设置器而不是通过Page本身的属性设置默认颜色(在本例中)。这是因为属性会覆盖触发器设置的值(因为它是一个样式触发器),所以即使触发器会触发,它也总是会被本地属性规范所取代,这意味着它不会改变。我只是指出这一点,因为这是一个相当普遍的问题。