Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
666 views
in Technique[技术] by (71.8m points)

xaml - How to vertically centre text in a Xamarin Forms Entry on UWP?

I have a Xamarin Forms project (v2.5) where I have a text Entry control in my Xaml file. I need the entry to be taller than default, so I specify a HeightRequest of 60, which works fine, apart from the text itself is aligned to the top of the Entry control.

<Entry Text="{Binding CustomerNameText}" HeightRequest="60" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" IsEnabled="{Binding CustomerNameEntryEnabled}" Focused="Entry_Focused" Unfocused="Entry_Unfocused" />

Which looks like:

enter image description here

I added a custom renderer:

public class CustomEntryRenderer : EntryRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);

        if(this.Control != null)
        {
            this.Control.VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center;
            this.Control.Height = 60;
        }

    }

}

But this doesn't work. The HeightRequest in the Xaml doesn't seem to work anymore, so I added the height in the custom renderer. But the text alignment stays at the top.

Can anyone tell me how to get the text vertically centered?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The correspondent native control of Entry is TextBox in UWP app, see Renderer Base Classes and Native Controls for more details. The VerticalAlignment property means that setting current control to vertical center in the parent control, not for the text inside. Only properties like TextAlignment will take effects on the text. Since Textbox in UWP app doesn't have the property VerticalTextAlignment, you cannot set the text to vertical center directly. But you could change the style template of TextBox as a workaround.

Create a new style for the Textbox, and to set the VerticalAlignment property to center to both ContentPresenter and ScrollViewer controls inside the ControlTemplate. And then apply the style in the custom render.

The style in App.xaml

<Style x:Key="TextBoxStyle1" TargetType="TextBox">
...
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TextBox">
                <Grid> 
                  ...
                    <Border x:Name="BorderElement" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Grid.ColumnSpan="2" Grid.RowSpan="1" Grid.Row="1"/>
                    <ContentPresenter  x:Name="HeaderContentPresenter" VerticalAlignment="Center"  ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.ColumnSpan="2" FontWeight="Normal" Foreground="{ThemeResource TextControlHeaderForeground}" Margin="0,0,0,8" Grid.Row="0" TextWrapping="{TemplateBinding TextWrapping}" Visibility="Collapsed" x:DeferLoadStrategy="Lazy"/>
                    <ScrollViewer x:Name="ContentElement" VerticalAlignment="Center" 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}" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" ZoomMode="Disabled"/>
                    <TextBlock x:Name="PlaceholderTextContentPresenter" Grid.ColumnSpan="2" Foreground="{Binding PlaceholderForeground, RelativeSource={RelativeSource Mode=TemplatedParent}, TargetNullValue={ThemeResource TextControlPlaceholderForeground}}" IsHitTestVisible="False" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1" Text="{TemplateBinding PlaceholderText}" TextWrapping="{TemplateBinding TextWrapping}" TextAlignment="{TemplateBinding TextAlignment}"/>
                    <Button x:Name="DeleteButton" AutomationProperties.AccessibilityView="Raw" BorderThickness="{TemplateBinding BorderThickness}" Grid.Column="1" FontSize="{TemplateBinding FontSize}" IsTabStop="False" MinWidth="34" Margin="{ThemeResource HelperButtonThemePadding}" Grid.Row="1" Style="{StaticResource DeleteButtonStyle}" VerticalAlignment="Stretch" Visibility="Collapsed"/>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Custom render:

protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
   base.OnElementChanged(e);

   if (this.Control != null)
   { 
       this.Control.Height = 60; 
       Control.Style = (Windows.UI.Xaml.Style)App.Current.Resources["TextBoxStyle1"];
   }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...