0

I try to create my UserControl which have a Label and TextBox. I want to my control have custom set of Visual States. So I wrote this code in xaml:

<UserControl x:Class="OgameApp.Components.TextField"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:OgameApp.Components"
         mc:Ignorable="d" 
         d:DesignWidth="500"
         Validation.ErrorTemplate="{x:Null}">

<UserControl.Resources>
    <Style TargetType="Label">
        <Setter Property="FontSize" Value="16" />
        <Setter Property="Padding" Value="0 0 0 5" />
        <Setter Property="Foreground" Value="#FF6D6D6D" />
    </Style>

    <Style TargetType="TextBox">
        <Setter Property="FontSize" Value="16" />
    </Style>
</UserControl.Resources>

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup Name="CommonStates">
        <VisualStateGroup.Transitions>
            <VisualTransition GeneratedDuration="0:0:3" />
        </VisualStateGroup.Transitions>

        <VisualState Name="Normal" />
        <VisualState Name="Focus">
            <Storyboard>
                <ColorAnimation To="Blue" Storyboard.TargetName="LabelControl" Storyboard.TargetProperty="Foreground" />
            </Storyboard>
        </VisualState>
        <VisualState Name="Success" />
        <VisualState Name="Error" />
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>


<StackPanel Name="WrapperControl">
    <Label Name="LabelControl" Content="Binding Label" />
    <TextBox Name="TextBoxControl" Text="{Binding Value}" Validation.Error="TextBox_Error" GotFocus="TextBox_GotFocus"/>
</StackPanel>

and in my UserControl class:

public partial class TextField : UserControl
{
    public static readonly DependencyProperty LabelProperty;
    public static readonly DependencyProperty ValueProperty;

    static TextField() {
        LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(TextField));
        ValueProperty = DependencyProperty.Register("Value", typeof(string), typeof(TextField));
    }

    public string Label
    {
        get { return (string)GetValue(LabelProperty); }
        set { SetValue(LabelProperty, value); }
    }

    public string Value
    {
        get
        {
            return (string)GetValue(ValueProperty);
        }
        set
        {
            SetValue(ValueProperty, value);
        }
    }

    public TextField()
    {
        InitializeComponent();

        WrapperControl.DataContext = this;
    }

    private void TextBox_Error(object sender, ValidationErrorEventArgs e)
    {
        VisualStateManager.GoToState(this, "Error", true);
    }

    private void TextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        VisualStateManager.GoToState(this, "Focus", true);
        VisualStateManager.GoToState(LabelControl, "Focus", true);
    }
}

So I was respect that when I focus in my control's Textbox element visual state of label will changing and foreground color changing to. But it not happens.

2 Answers2

0

You need to add a trigger for that.

Try to define a trigger for a mouse event, it will solve your problem.

<Style.Triggers>
<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="IsSelected" Value="True" />
        <Condition Property="IsMouseOver" Value="True" />
    </MultiTrigger.Conditions>
    <Setter ... />
</MultiTrigger>

100mil
  • 104
  • 8
  • Thank you for answer. But I not sure that what I need. After control is loaded it go to Normal state. When TextBox got focus the control has Focus state. And when TextBox lost focus Control may be one from two states Success or Error. – George Lemish Jul 05 '18 at 03:45
0

So after some hours I find solution.

First of all I try to move VisualStateManager.VisualStateGroups block inside StackPanel. Then I get the runtime error which explain that ColorAnimation can not set color to Foreground property. So I change it to Foreground.Color.

So this is my working xaml:

<UserControl x:Class="OgameApp.Components.TextField"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:OgameApp.Components"
         mc:Ignorable="d" 
         d:DesignWidth="500"
         Validation.ErrorTemplate="{x:Null}">

<UserControl.Resources>
    <Style TargetType="Label">
        <Setter Property="FontSize" Value="16" />
        <Setter Property="Padding" Value="0 0 0 5" />
        <Setter Property="Foreground" Value="#FF6D6D6D" />
    </Style>

    <Style TargetType="TextBox">
        <Setter Property="FontSize" Value="16" />
    </Style>
</UserControl.Resources>

<StackPanel Name="WrapperControl" Loaded="WrapperControl_Loaded">
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup Name="CommonStates">
            <VisualState Name="Normal" />
            <VisualState Name="Focus">
                <Storyboard>
                    <ColorAnimation Storyboard.TargetName="LabelControl" Storyboard.TargetProperty="Foreground.Color" To="Blue" Duration="0:0:3" />
                </Storyboard>
            </VisualState>
            <VisualState Name="Success" />
            <VisualState Name="Error" />
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

    <Label Name="LabelControl" Content="Binding Label" />
    <TextBox Name="TextBoxControl" Text="{Binding Value}" Validation.Error="TextBox_Error" GotFocus="TextBox_GotFocus"/>
</StackPanel>