user2921851
user2921851

Reputation: 990

Making a TextBox PlaceholderText wrap

This question has been asked already but thus far no answer. I find the TextBox PlaceholderText really useful as an indicator of some status info prior to text entry but the default non-wrap limits this useful feature.

Is there a solution to this?

Upvotes: 2

Views: 382

Answers (1)

Kristian Vukusic
Kristian Vukusic

Reputation: 3324

I will assume you are developing a Windows 10 (WinRT) app. You need to create a new style for your TextBox and edit the element that displays the placeholder text (in this case it is the CotentControl with the name PlaceholderTextContentPresenter):

<TextBox PlaceholderText="Long text that needs to wrap">
    <TextBox.Style>
        <!--  Default style for Windows.UI.Xaml.Controls.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>
                                <Style x:Name="DeleteButtonStyle" TargetType="Button">
                                    <Setter Property="Template">
                                        <Setter.Value>
                                            <ControlTemplate TargetType="Button">
                                                <Grid
                                                    x:Name="ButtonLayoutGrid"
                                                    Background="{ThemeResource TextBoxButtonBackgroundThemeBrush}"
                                                    BorderBrush="{ThemeResource TextBoxButtonBorderThemeBrush}"
                                                    BorderThickness="{TemplateBinding BorderThickness}">
                                                    <VisualStateManager.VisualStateGroups>
                                                        <VisualStateGroup x:Name="CommonStates">
                                                            <VisualState x:Name="Normal" />
                                                            <VisualState x:Name="PointerOver">
                                                                <Storyboard>
                                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="GlyphElement" Storyboard.TargetProperty="Foreground">
                                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAccentBrush}" />
                                                                    </ObjectAnimationUsingKeyFrames>
                                                                </Storyboard>
                                                            </VisualState>
                                                            <VisualState x:Name="Pressed">
                                                                <Storyboard>
                                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonLayoutGrid" Storyboard.TargetProperty="Background">
                                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAccentBrush}" />
                                                                    </ObjectAnimationUsingKeyFrames>
                                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="GlyphElement" Storyboard.TargetProperty="Foreground">
                                                                        <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltChromeWhiteBrush}" />
                                                                    </ObjectAnimationUsingKeyFrames>
                                                                </Storyboard>
                                                            </VisualState>
                                                            <VisualState x:Name="Disabled">
                                                                <Storyboard>
                                                                    <DoubleAnimation
                                                                        Duration="0"
                                                                        Storyboard.TargetName="ButtonLayoutGrid"
                                                                        Storyboard.TargetProperty="Opacity"
                                                                        To="0" />
                                                                </Storyboard>
                                                            </VisualState>
                                                        </VisualStateGroup>
                                                    </VisualStateManager.VisualStateGroups>
                                                    <TextBlock
                                                        x:Name="GlyphElement"
                                                        HorizontalAlignment="Center"
                                                        VerticalAlignment="Center"
                                                        AutomationProperties.AccessibilityView="Raw"
                                                        FontFamily="{ThemeResource SymbolThemeFontFamily}"
                                                        FontSize="12"
                                                        FontStyle="Normal"
                                                        Foreground="{ThemeResource SystemControlForegroundChromeBlackMediumBrush}"
                                                        Text="&#xE10A;" />
                                                </Grid>
                                            </ControlTemplate>
                                        </Setter.Value>
                                    </Setter>
                                </Style>
                            </Grid.Resources>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="HeaderContentPresenter" Storyboard.TargetProperty="Foreground">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseLowBrush}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundElement" Storyboard.TargetProperty="Background">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledTransparentBrush}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="Background">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseLowBrush}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="Foreground">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledChromeDisabledLowBrush}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter" Storyboard.TargetProperty="Foreground">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledChromeDisabledLowBrush}" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Normal" />
                                    <VisualState x:Name="PointerOver">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightChromeAltLowBrush}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundElement" Storyboard.TargetProperty="Opacity">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundHoverOpacity}" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Focused">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter" Storyboard.TargetProperty="Foreground">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlPageTextChromeBlackMediumLowBrush}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundElement" Storyboard.TargetProperty="Background">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundChromeWhiteBrush}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundElement" Storyboard.TargetProperty="Opacity">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextControlBackgroundFocusedOpacity}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAccentBrush}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="Foreground">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlForegroundChromeBlackHighBrush}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="RequestedTheme">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Light" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="ButtonStates">
                                    <VisualState x:Name="ButtonVisible">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DeleteButton" Storyboard.TargetProperty="Visibility">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="ButtonCollapsed" />
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="*" />
                            </Grid.RowDefinitions>
                            <Border
                                x:Name="BackgroundElement"
                                Grid.Row="1"
                                Grid.RowSpan="1"
                                Grid.ColumnSpan="2"
                                Margin="{TemplateBinding BorderThickness}"
                                Background="{TemplateBinding Background}"
                                Opacity="{ThemeResource TextControlBackgroundRestOpacity}" />
                            <Border
                                x:Name="BorderElement"
                                Grid.Row="1"
                                Grid.RowSpan="1"
                                Grid.ColumnSpan="2"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}" />
                            <ContentPresenter
                                x:Name="HeaderContentPresenter"
                                Grid.Row="0"
                                Grid.ColumnSpan="2"
                                Margin="0,0,0,8"
                                Content="{TemplateBinding Header}"
                                ContentTemplate="{TemplateBinding HeaderTemplate}"
                                FontWeight="Normal"
                                Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}"
                                Visibility="Collapsed"
                                x:DeferLoadStrategy="Lazy" />
                            <ScrollViewer
                                x:Name="ContentElement"
                                Grid.Row="1"
                                Margin="{TemplateBinding BorderThickness}"
                                AutomationProperties.AccessibilityView="Raw"
                                HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
                                HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
                                IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
                                IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
                                IsTabStop="False"
                                IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
                                Padding="{TemplateBinding Padding}"
                                VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
                                VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
                                ZoomMode="Disabled" />
                            <ContentControl
                                x:Name="PlaceholderTextContentPresenter"
                                Grid.Row="1"
                                Grid.ColumnSpan="2"
                                Margin="{TemplateBinding BorderThickness}"
                                Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}"
                                IsHitTestVisible="False"
                                IsTabStop="False"
                                Padding="{TemplateBinding Padding}" >
                                <ContentControl.Content>
                                    <TextBlock TextWrapping="Wrap" Text="{TemplateBinding PlaceholderText}"/>
                                </ContentControl.Content>
                            </ContentControl>
                            <Button
                                x:Name="DeleteButton"
                                Grid.Row="1"
                                Grid.Column="1"
                                MinWidth="34"
                                Margin="{ThemeResource HelperButtonThemePadding}"
                                VerticalAlignment="Stretch"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                FontSize="{TemplateBinding FontSize}"
                                IsTabStop="False"
                                Style="{StaticResource DeleteButtonStyle}"
                                Visibility="Collapsed" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </TextBox.Style>
</TextBox>

I have changed the Content property to be a TextBlock with the TextWrapping property set.

For other platforms this is basically the same, you just need to edit the default style of the TextBox control. You can generate those either in Visual Studio itself (in XAML designer view -> right click -> Edit Templates ...), or find it on the internet.

Upvotes: 3

Related Questions