Reputation: 222
I need to change a background color for my TextBox if the TextBox IsReadOnly.
In WPF i had following Style:
<Style TargetType="TextBox">
<Setter Property="Background" Value="{StaticResource ControlBackgroundColorBrush}" />
<Setter Property="Foreground" Value="{StaticResource PrimaryColorBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource SecondaryColorBrush}" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="IsReadOnlyCaretVisible" Value="False" />
<Setter Property="Validation.ErrorTemplate" Value="{StaticResource DefaultErrorTemplate}" />
<Style.Triggers>
<Trigger Property="IsReadOnly" Value="True">
<Setter Property="BorderBrush" Value="{StaticResource ControlBackgroundColorBrush}" />
<Setter Property="IsHitTestVisible" Value="False" />
</Trigger>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self},Path=(Validation.Errors)[0].ErrorContent}" />
</Trigger>
</Style.Triggers>
</Style>
But in UWP is Style.Trigger not available. I try to solve this problem with VisualState. I get a Template of TextBox (from Blend) and manipulate this, but it does not work. Here my Style for the TextBox:
<Style TargetType="TextBox">
<Setter Property="MinWidth" Value="{ThemeResource TextControlThemeMinWidth}" />
<Setter Property="MinHeight" Value="{ThemeResource TextControlThemeMinHeight}" />
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}" />
<Setter Property="Background" Value="{ThemeResource SystemControlBackgroundAltHighBrush}" />
<Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundChromeDisabledLowBrush}" />
<Setter Property="SelectionHighlightColor" Value="{ThemeResource SystemControlHighlightAccentBrush}" />
<Setter Property="BorderThickness" Value="{ThemeResource TextControlBorderThemeThickness}" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden" />
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False" />
<Setter Property="Padding" Value="{ThemeResource TextControlThemePadding}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Grid>
<Grid.Resources>
<Storyboard x:Name="Storyboard1" />
</Grid.Resources>
<Grid.Background>
<StaticResource ResourceKey="ControlBackgroundColorBrush" />
</Grid.Background>
<Grid.BorderBrush>
<StaticResource ResourceKey="ControlBackgroundColorBrush" />
</Grid.BorderBrush>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="ReadOnly">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="PlaceholderTextContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource HighlightColorBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundChromeWhiteBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundFocusedOpacity}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ButtonStates">
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="BackgroundElement" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" Margin="{TemplateBinding BorderThickness}" Opacity="{ThemeResource TextControlBackgroundRestOpacity}" Grid.Row="1" Grid.RowSpan="1" />
<Border x:Name="BorderElement" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Grid.ColumnSpan="2" Grid.Row="1" Grid.RowSpan="1" />
<ContentPresenter x:Name="HeaderContentPresenter" Grid.ColumnSpan="2" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}" FontWeight="Normal" Margin="0,0,0,8" Grid.Row="0" Visibility="Collapsed" x:DeferLoadStrategy="Lazy" />
<Border x:Name="ContentElement" AutomationProperties.AccessibilityView="Raw" ScrollViewer.HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" ScrollViewer.HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" ScrollViewer.IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" ScrollViewer.IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" ScrollViewer.IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" Padding="{TemplateBinding Padding}" Grid.Row="1" ScrollViewer.VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" ScrollViewer.VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ScrollViewer.ZoomMode="Disabled" />
<ContentControl x:Name="PlaceholderTextContentPresenter" Grid.ColumnSpan="2" Content="{TemplateBinding PlaceholderText}" Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}" IsHitTestVisible="False" IsTabStop="False" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Any idea how to solve the Problem???
Upvotes: 1
Views: 1393
Reputation: 401
Try 'IsEnabled' flag of TextBox for getting effect that you need. You need style 'disabled' visual state for the TextBox:
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled">
<!--Here your style for disabled TextBox-->
</VisualState>
</VisualStateGroup>
and set 'IsEnabled' to false.
Or use triggers as @nicetry answered
Upvotes: 0
Reputation: 101
There is no built-in "ReadOnly" visual state in TextBox. But you can add your own VisualStateGroup with VisualState in it and then use StateTrigger.
<Style TargetType="TextBox">
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Grid>
...
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled">
...
</VisualState>
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
...
</VisualState>
<VisualState x:Name="Focused">
...
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ButtonStates">
<VisualState x:Name="ButtonVisible">
...
</VisualState>
<VisualState x:Name="ButtonCollapsed" />
</VisualStateGroup>
<VisualStateGroup>
<VisualState>
<VisualState.StateTriggers>
<StateTrigger IsActive="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"/>
</VisualState.StateTriggers>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="PlaceholderTextContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource HighlightColorBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="BackgroundElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundChromeWhiteBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity" Storyboard.TargetName="BackgroundElement">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundFocusedOpacity}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
...
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Upvotes: 1
Reputation: 1195
For example, you can just create your own custom TextBox control which inherits from TextBox
and check IsReadOnly
property in overridden OnApplyTemplate
method, like that:
public class CustomTextBox : TextBox
{
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
if (IsReadOnly)
{
Background = new SolidColorBrush(Colors.Red); //eg. set Background to Red
IsHitTestVisible = false; //Additionally you can set IsHitTestVisible if it should be really readonly
}
}
}
and use your new control in xaml:
<local:CustomTextBox Width="200"
Height="50"
IsReadOnly="True" />
Upvotes: 0