在WPF中,如何在具有焦点的窗口部分周围放置边框?

时间:2010-06-24 02:39:39

标签: wpf focus border

我有一个有两个主要区域的窗口。一个是ScrollViewer内部的TextBox,另一个是TabControl。我想在当前具有焦点的部分周围有一个红色边框,所以我编写了以下代码来做到这一点

的Xaml

<ScrollViewer BorderBrush="Red" 
              BorderThickness="0"
              GotFocus="Border_GotFocus"  
              LostFocus="Border_LostFocus">
    <TextBox/>
</ScrollViewer>
<TabControl BorderBrush="Red" 
            BorderThickness="0"
            GotFocus="Border_GotFocus"  
            LostFocus="Border_LostFocus">
</TabControl>

代码

private void Border_LostFocus(object sender, RoutedEventArgs e)
{
    var control = sender as Control;
    if (control != null)
    {
        control.BorderThickness = new Thickness(0);
    }
}

private void Border_GotFocus(object sender, RoutedEventArgs e)
{
    var control = sender as Control;
    if (control != null)
    {
        control.BorderThickness = new Thickness(2);
    }
}

问题是,如果我点击TextBox,它不会更新ScrollViewer周围的边框。如果我单击TabControl中的Tab,它会更新边框,以便我可以看到边框,但是当我点击其他地方时不会“删除”它。有没有更好的方法来做到这一点?

2 个答案:

答案 0 :(得分:6)

首先,我强烈建议不要使用代码并将其保留在XAML中。

其次,我还建议使用Border来执行此操作。

第三,我在你的样式触发器中使用IsKeyboardFocusedWithin。

<Window.Resources>
    <Style x:Key="FocusedBorder" TargetType="Border">
        <Setter Property="BorderThickness" Value="2"></Setter>
        <Setter Property="BorderBrush" Value="Transparent"></Setter>
        <Style.Triggers>
            <Trigger Property="IsKeyboardFocusWithin" Value="True">
                <Setter Property="BorderBrush" Value="Red"></Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<StackPanel Width="400">
    <ScrollViewer>
        <Border Style="{StaticResource FocusedBorder}">
            <TextBox>
            </TextBox>
        </Border>
    </ScrollViewer>
    <TabControl>
        <TabItem Header="Foo">
            <Border Style="{StaticResource FocusedBorder}">
                <TextBox></TextBox>
            </Border>
        </TabItem>
        <TabItem Header="Bar">
            <Border Style="{StaticResource FocusedBorder}">
                <TextBox></TextBox>
            </Border>
        </TabItem>
    </TabControl>
</StackPanel>

答案 1 :(得分:0)

接受的答案对我不起作用。然而,我想出了一种不使用边框并且仍能获得相同效果的方法。

以下是文本框使用的样式。

<Style x:Key="DefaultTextbox" TargetType="{x:Type TextBox}">
    <Setter Property="FontSize" Value="14" />
    <Setter Property="VerticalAlignment" Value="Center" />
    <Setter Property="Margin" Value="5 2 10 2" />
    <Setter Property="FontFamily" Value="Arial" />
    <Setter Property="FontStyle" Value="Normal" />
    <Setter Property="BorderThickness" Value="2" />
    <Setter Property="BorderBrush" Value="Transparent" />
    <Style.Triggers>
        <Trigger Property="IsFocused" Value="True" >
            <Setter Property="BorderBrush" Value="#4E82EC" />
        </Trigger>
    </Style.Triggers>
</Style>

我的风格确实遇到了一些麻烦。最初我在触发器中声明了边框粗细和颜色。问题是当盒子里有文字时,它似乎跳了起来。绕过跳跃效果是默认声明边框粗细并将边框设置为透明,因此当焦点上的颜色发生变化时,就没有跳跃效果。

然后您只需将样式设置为文本框:

<TextBox Style="{StaticResource DefaultTextbox}" />

这就是你会看到的效果。

Sample of what a focused and non focused textbox looks like