【WP8】让TextBox文本支持滑动(Scroll)

通过修改样式让TextBox支持文本滑动

  在Silverlight上,TextBox是有文本滚动的功能的,当TextBox的文本过长时,可以进行拖动的,TextBox使用 VerticalScrollBarVisibility 和 HorizontalScrollBarVisibility 来控制滚动条的显示

在Windows Phone上的TextBox 也拥有 VerticalScrollBarVisibility 和 HorizontalScrollBarVisibility 两个属性,但是当设置这两个属性Visible后,却发现TextBox上的文本滑动不了,下面对比Silverlight和WP上的TextBox样式

WP8上的TextBox样式如下:

【WP8】让TextBox文本支持滑动(Scroll)
    <Style x:Key="TextBoxStyle1" TargetType="TextBox">

        <Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>

        <Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>

        <Setter Property="Background" Value="{StaticResource PhoneTextBoxBrush}"/>

        <Setter Property="Foreground" Value="{StaticResource PhoneTextBoxForegroundBrush}"/>

        <Setter Property="BorderBrush" Value="{StaticResource PhoneTextBoxBrush}"/>

        <Setter Property="SelectionBackground" Value="{StaticResource PhoneAccentBrush}"/>

        <Setter Property="SelectionForeground" Value="{StaticResource PhoneTextBoxSelectionForegroundBrush}"/>

        <Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>

        <Setter Property="Padding" Value="2"/>

        <Setter Property="Template">

            <Setter.Value>

                <ControlTemplate TargetType="TextBox">

                    <Grid Background="Transparent">

                        <VisualStateManager.VisualStateGroups>

                            <VisualStateGroup x:Name="CommonStates">

                                <VisualState x:Name="Normal"/>

                                <VisualState x:Name="MouseOver"/>

                                <VisualState x:Name="Disabled">

                                    <Storyboard>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="MainBorder">

                                            <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>

                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="MainBorder">

                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>

                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">

                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>

                                        </ObjectAnimationUsingKeyFrames>

                                    </Storyboard>

                                </VisualState>

                                <VisualState x:Name="ReadOnly">

                                    <Storyboard>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="MainBorder">

                                            <DiscreteObjectKeyFrame KeyTime="0">

                                                <DiscreteObjectKeyFrame.Value>

                                                    <Visibility>Collapsed</Visibility>

                                                </DiscreteObjectKeyFrame.Value>

                                            </DiscreteObjectKeyFrame>

                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ReadonlyBorder">

                                            <DiscreteObjectKeyFrame KeyTime="0">

                                                <DiscreteObjectKeyFrame.Value>

                                                    <Visibility>Visible</Visibility>

                                                </DiscreteObjectKeyFrame.Value>

                                            </DiscreteObjectKeyFrame>

                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ReadonlyBorder">

                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/>

                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ReadonlyBorder">

                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/>

                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">

                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxReadOnlyBrush}"/>

                                        </ObjectAnimationUsingKeyFrames>

                                    </Storyboard>

                                </VisualState>

                            </VisualStateGroup>

                            <VisualStateGroup x:Name="FocusStates">

                                <VisualState x:Name="Focused">

                                    <Storyboard>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="MainBorder">

                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBackgroundBrush}"/>

                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="MainBorder">

                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBorderBrush}"/>

                                        </ObjectAnimationUsingKeyFrames>

                                    </Storyboard>

                                </VisualState>

                                <VisualState x:Name="Unfocused"/>

                            </VisualStateGroup>

                        </VisualStateManager.VisualStateGroups>

                        <Border x:Name="MainBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}"/>

                        <Border x:Name="ReadonlyBorder" BorderBrush="{StaticResource PhoneDisabledBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}" Visibility="Collapsed"/>

                        <Border BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}">

                            <ContentControl x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="{StaticResource PhoneTextBoxInnerMargin}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/>

                        </Border>

                    </Grid>

                </ControlTemplate>

            </Setter.Value>

        </Setter>

    </Style>
WP8上TextBox默认样式

Silverlight上的TextBox样式如下(Silverlight支持文本滚动)

【WP8】让TextBox文本支持滑动(Scroll)
    <ControlTemplate x:Key="ValidationToolTipTemplate">

        <Grid x:Name="Root" Margin="5,0" Opacity="0" RenderTransformOrigin="0,0">

            <Grid.RenderTransform>

                <TranslateTransform x:Name="xform" X="-25"/>

            </Grid.RenderTransform>

            <VisualStateManager.VisualStateGroups>

                <VisualStateGroup x:Name="OpenStates">

                    <VisualStateGroup.Transitions>

                        <VisualTransition GeneratedDuration="0"/>

                        <VisualTransition GeneratedDuration="0:0:0.2" To="Open">

                            <Storyboard>

                                <DoubleAnimation Duration="0:0:0.2" To="0" Storyboard.TargetProperty="X" Storyboard.TargetName="xform">

                                    <DoubleAnimation.EasingFunction>

                                        <BackEase Amplitude=".3" EasingMode="EaseOut"/>

                                    </DoubleAnimation.EasingFunction>

                                </DoubleAnimation>

                                <DoubleAnimation Duration="0:0:0.2" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>

                            </Storyboard>

                        </VisualTransition>

                    </VisualStateGroup.Transitions>

                    <VisualState x:Name="Closed">

                        <Storyboard>

                            <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>

                        </Storyboard>

                    </VisualState>

                    <VisualState x:Name="Open">

                        <Storyboard>

                            <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="X" Storyboard.TargetName="xform"/>

                            <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="Root"/>

                        </Storyboard>

                    </VisualState>

                </VisualStateGroup>

            </VisualStateManager.VisualStateGroups>

            <Border Background="#052A2E31" CornerRadius="5" Margin="4,4,-4,-4"/>

            <Border Background="#152A2E31" CornerRadius="4" Margin="3,3,-3,-3"/>

            <Border Background="#252A2E31" CornerRadius="3" Margin="2,2,-2,-2"/>

            <Border Background="#352A2E31" CornerRadius="2" Margin="1,1,-1,-1"/>

            <Border Background="#FFDC000C" CornerRadius="2"/>

            <Border CornerRadius="2">

                <TextBlock Foreground="White" MaxWidth="250" Margin="8,4,8,4" TextWrapping="Wrap" Text="{Binding (Validation.Errors)[0].ErrorContent}" UseLayoutRounding="false"/>

            </Border>

        </Grid>

    </ControlTemplate>

    <Style x:Key="TextBoxStyle1" TargetType="TextBox">

        <Setter Property="Template">

            <Setter.Value>

                <ControlTemplate TargetType="TextBox">

                    <Grid x:Name="RootElement">

                        <VisualStateManager.VisualStateGroups>

                            <VisualStateGroup x:Name="CommonStates">

                                <VisualState x:Name="Normal"/>

                                <VisualState x:Name="MouseOver">

                                    <Storyboard>

                                        <ColorAnimation Duration="0" To="#FF99C1E2" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="MouseOverBorder"/>

                                    </Storyboard>

                                </VisualState>

                                <VisualState x:Name="Disabled">

                                    <Storyboard>

                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisabledVisualElement"/>

                                    </Storyboard>

                                </VisualState>

                                <VisualState x:Name="ReadOnly">

                                    <Storyboard>

                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ReadOnlyVisualElement"/>

                                    </Storyboard>

                                </VisualState>

                            </VisualStateGroup>

                            <VisualStateGroup x:Name="FocusStates">

                                <VisualState x:Name="Focused">

                                    <Storyboard>

                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualElement"/>

                                    </Storyboard>

                                </VisualState>

                                <VisualState x:Name="Unfocused">

                                    <Storyboard>

                                        <DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualElement"/>

                                    </Storyboard>

                                </VisualState>

                            </VisualStateGroup>

                            <VisualStateGroup x:Name="ValidationStates">

                                <VisualState x:Name="Valid"/>

                                <VisualState x:Name="InvalidUnfocused">

                                    <Storyboard>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ValidationErrorElement">

                                            <DiscreteObjectKeyFrame KeyTime="0">

                                                <DiscreteObjectKeyFrame.Value>

                                                    <Visibility>Visible</Visibility>

                                                </DiscreteObjectKeyFrame.Value>

                                            </DiscreteObjectKeyFrame>

                                        </ObjectAnimationUsingKeyFrames>

                                    </Storyboard>

                                </VisualState>

                                <VisualState x:Name="InvalidFocused">

                                    <Storyboard>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ValidationErrorElement">

                                            <DiscreteObjectKeyFrame KeyTime="0">

                                                <DiscreteObjectKeyFrame.Value>

                                                    <Visibility>Visible</Visibility>

                                                </DiscreteObjectKeyFrame.Value>

                                            </DiscreteObjectKeyFrame>

                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsOpen" Storyboard.TargetName="validationTooltip">

                                            <DiscreteObjectKeyFrame KeyTime="0">

                                                <DiscreteObjectKeyFrame.Value>

                                                    <system:Boolean>True</system:Boolean>

                                                </DiscreteObjectKeyFrame.Value>

                                            </DiscreteObjectKeyFrame>

                                        </ObjectAnimationUsingKeyFrames>

                                    </Storyboard>

                                </VisualState>

                            </VisualStateGroup>

                        </VisualStateManager.VisualStateGroups>

                        <Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}">

                            <Grid>

                                <Border x:Name="ReadOnlyVisualElement" Background="#5EC9C9C9" Opacity="0"/>

                                <Border x:Name="MouseOverBorder" BorderBrush="Transparent" BorderThickness="1">

                                    <ScrollViewer x:Name="ContentElement" BorderThickness="0" IsTabStop="False" Padding="{TemplateBinding Padding}"/>

                                </Border>

                            </Grid>

                        </Border>

                        <Border x:Name="DisabledVisualElement" BorderBrush="#A5F7F7F7" BorderThickness="{TemplateBinding BorderThickness}" Background="#A5F7F7F7" IsHitTestVisible="False" Opacity="0"/>

                        <Border x:Name="FocusVisualElement" BorderBrush="#FF6DBDD1" BorderThickness="{TemplateBinding BorderThickness}" IsHitTestVisible="False" Margin="1" Opacity="0"/>

                        <Border x:Name="ValidationErrorElement" BorderBrush="#FFDB000C" BorderThickness="1" CornerRadius="1" Visibility="Collapsed">

                            <ToolTipService.ToolTip>

                                <ToolTip x:Name="validationTooltip" DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}" Placement="Right" PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" Template="{StaticResource ValidationToolTipTemplate}">

                                    <ToolTip.Triggers>

                                        <EventTrigger RoutedEvent="Canvas.Loaded">

                                            <BeginStoryboard>

                                                <Storyboard>

                                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="IsHitTestVisible" Storyboard.TargetName="validationTooltip">

                                                        <DiscreteObjectKeyFrame KeyTime="0">

                                                            <DiscreteObjectKeyFrame.Value>

                                                                <system:Boolean>true</system:Boolean>

                                                            </DiscreteObjectKeyFrame.Value>

                                                        </DiscreteObjectKeyFrame>

                                                    </ObjectAnimationUsingKeyFrames>

                                                </Storyboard>

                                            </BeginStoryboard>

                                        </EventTrigger>

                                    </ToolTip.Triggers>

                                </ToolTip>

                            </ToolTipService.ToolTip>

                            <Grid Background="Transparent" HorizontalAlignment="Right" Height="12" Margin="1,-4,-4,0" VerticalAlignment="Top" Width="12">

                                <Path Data="M 1,0 L6,0 A 2,2 90 0 1 8,2 L8,7 z" Fill="#FFDC000C" Margin="1,3,0,0"/>

                                <Path Data="M 0,0 L2,0 L 8,6 L8,8" Fill="#ffffff" Margin="1,3,0,0"/>

                            </Grid>

                        </Border>

                    </Grid>

                </ControlTemplate>

            </Setter.Value>

        </Setter>

    </Style>
Silverlight上TextBox默认样式

 

通过对比TextBox的样式发现,WP8上的TextBox样式模板里面并没有ScrollViewer控件,而Silverlight中的TextBox是有ScrollViewer的,可以正常滚动,我们把WP8上的TextBox样式中的ContentControl改为ScrollViewer

【WP8】让TextBox文本支持滑动(Scroll)
    <Style x:Key="TextBoxStyle2" TargetType="TextBox">

        <Setter Property="Template">

            <Setter.Value>

                <ControlTemplate TargetType="TextBox">

                    <Grid Background="Transparent">

                        <VisualStateManager.VisualStateGroups>

                            <VisualStateGroup x:Name="CommonStates">

                                <VisualState x:Name="Normal"/>

                                <VisualState x:Name="MouseOver"/>

                                <VisualState x:Name="Disabled">

                                    <Storyboard>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="MainBorder">

                                            <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>

                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="MainBorder">

                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>

                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">

                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>

                                        </ObjectAnimationUsingKeyFrames>

                                    </Storyboard>

                                </VisualState>

                                <VisualState x:Name="ReadOnly">

                                    <Storyboard>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="MainBorder">

                                            <DiscreteObjectKeyFrame KeyTime="0">

                                                <DiscreteObjectKeyFrame.Value>

                                                    <Visibility>Collapsed</Visibility>

                                                </DiscreteObjectKeyFrame.Value>

                                            </DiscreteObjectKeyFrame>

                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="ReadonlyBorder">

                                            <DiscreteObjectKeyFrame KeyTime="0">

                                                <DiscreteObjectKeyFrame.Value>

                                                    <Visibility>Visible</Visibility>

                                                </DiscreteObjectKeyFrame.Value>

                                            </DiscreteObjectKeyFrame>

                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ReadonlyBorder">

                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/>

                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="ReadonlyBorder">

                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxBrush}"/>

                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentElement">

                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxReadOnlyBrush}"/>

                                        </ObjectAnimationUsingKeyFrames>

                                    </Storyboard>

                                </VisualState>

                            </VisualStateGroup>

                            <VisualStateGroup x:Name="FocusStates">

                                <VisualState x:Name="Focused">

                                    <Storyboard>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="MainBorder">

                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBackgroundBrush}"/>

                                        </ObjectAnimationUsingKeyFrames>

                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="MainBorder">

                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxEditBorderBrush}"/>

                                        </ObjectAnimationUsingKeyFrames>

                                    </Storyboard>

                                </VisualState>

                                <VisualState x:Name="Unfocused"/>

                            </VisualStateGroup>

                        </VisualStateManager.VisualStateGroups>

                        <Border x:Name="MainBorder" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}"/>

                        <Border x:Name="ReadonlyBorder" BorderBrush="{StaticResource PhoneDisabledBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}" Visibility="Collapsed"/>

                        <Border BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent" Margin="{StaticResource PhoneTouchTargetOverhang}">

                            <ScrollViewer x:Name="ContentElement" BorderThickness="0" IsTabStop="False" Padding="{TemplateBinding Padding}" Margin="{StaticResource PhoneTextBoxInnerMargin}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"/>

                        </Border>

                    </Grid>

                </ControlTemplate>

            </Setter.Value>

        </Setter>

    </Style>
WP8的TextBox修改后的样式

测试后发现,WP8上的TextBox可以滑动了(但发现看不到ScrollBar)

 

控制TextBox显示文本的位置

  有时候我们需要在代码中向TextBox的Text添加内容,比如表情,这时候TextBox不在编辑状态,我们添加文本后可以通过TextBox.SelectionStart去控制TextBox显示的位置,添加内容后TextBox.SelectionStart会被设置为0,如果需要显示文本的末尾,可以用 textBox.SelectionStart = textBox.Text.Length - 1; 

 

你可能感兴趣的:(scroll)