动态地将TextBox的BorderBrush应用于Border的BorderBrush

时间:2016-07-18 09:24:46

标签: wpf xaml binding styling mahapps.metro

我的申请中有TextBoxesFakeTextBoxesFakeTextBoxes充当TextBoxes,但由于其中包含按钮和/或图像,因此它们具有更多功能。 XAML的{​​{1}}看起来像这样:

FakeTextBox
我的项目中的

<Border BorderThickness="1"> <StackPanel Orientation="Horizontal"> <TextBox BorderThickness="0" /> <Button>I'm a button inside textbox</Button> </StackPanel> </Border> 具有自定义样式,可根据其TextBoxBorderBrush属性更改其IsMouseOver。通用样式来自mahapps.metro,你可以在这里找到它:https://github.com/MahApps/MahApps.Metro/blob/develop/MahApps.Metro/Styles/Controls.TextBox.xaml

问题在于我无法对GotFocus的边框应用相同的行为。我希望在我的自定义FakeTextBox上拥有完全相同的行为,以便它看起来与其他Border es完全相同。

我尝试过的工作并没有为TextBox工作:

  • 绑定到内部Border的{​​{1}}属性。
  • 绑定到BorderBrush的{​​{1}}属性:IsFocused没有设置器。
  • 创建隐藏的TextBox并绑定到其IsFocused

是否有通用和/或简单的解决方案?

2 个答案:

答案 0 :(得分:2)

由于您要复制边境行为,让我们在TextBox Style中查找BorderBrushes以及它们是如何实现的。找到三个,让他们的密钥访问Colors部分。

<Border BorderThickness="1">
    <Border.Resources>
        <Color x:Key="BlackColor">#FF000000</Color>
        <Color x:Key="Gray2">#FF7F7F7F</Color>
        <Color x:Key="Gray6">#FFCCCCCC</Color>
        <SolidColorBrush x:Key="TextBoxBorderBrush" Color="{StaticResource Gray6}" />
        <SolidColorBrush x:Key="TextBoxMouseOverBorderBrush" Color="{StaticResource Gray2}" />
        <SolidColorBrush x:Key="TextBoxFocusBorderBrush" Color="{StaticResource BlackColor}" />
    </Border.Resources>
    <Border.Style>
        <Style TargetType="{x:Type Border}">
            <Setter Property="BorderBrush" Value="{StaticResource TextBoxBorderBrush}" />
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="BorderBrush" Value="{StaticResource TextBoxMouseOverBorderBrush}" /> 
                </Trigger>
                <EventTrigger RoutedEvent="Control.GotFocus">
                    <BeginStoryboard>
                        <Storyboard>
                            <ColorAnimation Storyboard.TargetProperty="BorderBrush.Color" To="White" Duration="0:0:0.250"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Style.Triggers>
        </Style>
    </Border.Style>
    <StackPanel>
        <TextBox BorderThickness="0" />
        <Button>I'm a button inside textbox</Button>
    </StackPanel>
</Border>

IsFocused BorderBrush很棘手,因为它是你所追求的TextBox的IsFocused属性。如果做得对,你会想要在边框上声明一个Attached Property IsFocused并将它绑定到TextBox的IsFocused或者将它组合成一个自定义边框。

答案 1 :(得分:0)

我遇到了无数问题。

我的解决方案是创建三个不同的边界。

  • FocusBorder
  • MouseOverBorder
  • NormalBorder

FocusBorder位于顶部,MouseOverBorder停留在中间层,NormalBorder位于最低级别。

FocusBorder的可见性由Control.GotFocusControl.LostFocus事件触发器决定。与Control.MouseEnterControl.MouseLeave事件的MouseOverBorder相同的行为。

<UserControl.Triggers>
        <EventTrigger RoutedEvent="Control.GotFocus">
            <BeginStoryboard>
                <Storyboard>
                    <ObjectAnimationUsingKeyFrames
                                        Storyboard.TargetName="FocusBorder"
                                        Storyboard.TargetProperty="Visibility"
                                        Duration="1">
                        <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                                <Visibility>Visible</Visibility>
                            </DiscreteObjectKeyFrame.Value>
                        </DiscreteObjectKeyFrame>
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
        <EventTrigger RoutedEvent="Control.LostFocus">
            <BeginStoryboard>
                <Storyboard>
                    <ObjectAnimationUsingKeyFrames
                                        Storyboard.TargetName="FocusBorder"
                                        Storyboard.TargetProperty="Visibility"
                                        Duration="1">
                        <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                                <Visibility>Collapsed</Visibility>
                            </DiscreteObjectKeyFrame.Value>
                        </DiscreteObjectKeyFrame>
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
        <EventTrigger RoutedEvent="Control.MouseEnter">
            <BeginStoryboard>
                <Storyboard>
                    <ObjectAnimationUsingKeyFrames
                                        Storyboard.TargetName="MouseOverBorder"
                                        Storyboard.TargetProperty="Visibility"
                                        Duration="1">
                        <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                                <Visibility>Visible</Visibility>
                            </DiscreteObjectKeyFrame.Value>
                        </DiscreteObjectKeyFrame>
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
        <EventTrigger RoutedEvent="Control.MouseLeave">
            <BeginStoryboard>
                <Storyboard>
                    <ObjectAnimationUsingKeyFrames
                                        Storyboard.TargetName="MouseOverBorder"
                                        Storyboard.TargetProperty="Visibility"
                                        Duration="1">
                        <DiscreteObjectKeyFrame KeyTime="0">
                            <DiscreteObjectKeyFrame.Value>
                                <Visibility>Collapsed</Visibility>
                            </DiscreteObjectKeyFrame.Value>
                        </DiscreteObjectKeyFrame>
                    </ObjectAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </UserControl.Triggers>
    <Grid>
        <Border x:Name="FocusBorder" BorderBrush="{DynamicResource ComboBoxMouseOverInnerBorderBrush}"
                Canvas.ZIndex="3" BorderThickness="1" Visibility="Collapsed" />
        <Border x:Name="MouseOverBorder" BorderBrush="{DynamicResource TextBoxMouseOverBorderBrush}"
                Canvas.ZIndex="2" BorderThickness="1" Visibility="Collapsed" />
        <Border BorderBrush="{DynamicResource TextBoxBorderBrush}"
                Canvas.ZIndex="1"  BorderThickness="1" />
        <TextBox BorderThickness="0"></TextBox>
    </Grid>