Applying BorderBrush of TextBox to BorderBrush of a Border dynamically

wpf xaml binding styling mahapps.metro

551 просмотра

2 ответа

250 Репутация автора

I have TextBoxes and FakeTextBoxes in my application. FakeTextBoxes acts as TextBoxes, but they have more functionality as they have buttons, and/or images inside it. XAML for a FakeTextBox looks something like this:

                <Border BorderThickness="1">
                    <StackPanel Orientation="Horizontal">
                        <TextBox BorderThickness="0" />
                        <Button>I'm a button inside textbox</Button>
                    </StackPanel>
                </Border>

TextBox in my project have a custom styling that changes its BorderBrush depending on its IsMouseOver and GotFocus properties. The generic style comes from mahapps.metro and you can find it here : https://github.com/MahApps/MahApps.Metro/blob/develop/MahApps.Metro/Styles/Controls.TextBox.xaml

The problem is that I can't apply the same behaviour for the border of my FakeTextBox. I want to have the exactly same behavior on my custom Border so that it'll look like exactly the same as other TextBoxes.

What I've tried and didn't work for Border:

  • Binding to BorderBrush property of inner TextBox.
  • Binding to IsFocused property of TextBox : IsFocused has no setter.
  • Creating a hidden TextBox and binding to its BorderBrush

Is there a generic and/or easy solution to it?

Автор: U. Bulle Источник Размещён: 18.07.2016 09:24

Ответы (2)


2 плюса

6895 Репутация автора

Since you want to copy Border behaviour, lets look for BorderBrushes in the TextBox Style en how they're implemented. Found three, to get their Keys a visit to the Colors section.

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

The IsFocused BorderBrush is tricky because it's the TextBox's IsFocused property you're after. Doing it right you would want to declare an Attached Property IsFocused on the Border and bind it to the TextBox's IsFocused or make it a Custom Border all together.

Автор: Funk Размещён: 19.07.2016 02:41

0 плюса

250 Репутация автора

Решение

I have had countless problems with this one.

The solution for me was to create three different borders.

  • FocusBorder
  • MouseOverBorder
  • NormalBorder

FocusBorder stays on the top, MouseOverBorder stays in the middle layer, and NormalBorder in the lowest level.

Visibility of FocusBorderis decided by Control.GotFocus and Control.LostFocus event triggers. Same behavior for the MouseOverBorder for Control.MouseEnter and Control.MouseLeave events.

<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>
Автор: U. Bulle Размещён: 01.08.2016 06:14
Вопросы из категории :
32x32