web-dev-qa-db-fra.com

Est-il possible de faire en sorte qu'une étiquette remplisse l'espace de gauche à droite?

Voici le code que j'ai:

<StackLayout>
   <Label x:Name="emptyLabel1" FontSize="18" XAlign="Start" TextColor="Gray" />
   <Label x:Name="emptyLabel2" FontSize="18" XAlign="Center" TextColor="Gray" />
   <Label x:Name="emptyLabel3" FontSize="18" XAlign="Center" TextColor="Gray" />
</StackLayout>

La première étiquette multiligne commence à gauche mais comporte des espaces sur certaines des lignes à droite. Les deuxième et troisième étiquettes multilignes sont centrées et comportent des espaces à gauche et à droite. 

Est-il possible que toutes les lignes des étiquettes remplissent complètement les lignes de gauche à droite o que le premier caractère de chaque ligne est toujours aligné à gauche et que le dernier caractère du dernier mot de chaque ligne contient toujours des lignes sur la droite? Notez que cela nécessiterait que quelques mots dans chaque ligne aient des espaces différents entre eux. 

16
Alan2

Il est un peu délicat d’implémenter une étiquette avec un support d’alignement justifié, mais cela est possible grâce au rendu de la plate-forme.

La première étape serait de déclarer un contrôle personnalisé dans un projet de formulaires. 

public class JustifiedLabel : Label { }

L'étape suivante consiste à définir et à enregistrer le rendu de la plateforme dans iOS. Celui-ci est simple, nous combinons simplement une chaîne formatée avec un style de paragraphe pour obtenir ce que nous voulons. 

[Assembly: ExportRenderer(typeof(JustifiedLabel), typeof(JustifiedLabelRenderer))]
namespace SomeAppNamespace.iOS
{   
    public class JustifiedLabelRenderer : LabelRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);

            //if we have a new forms element, we want to update text with font style (as specified in forms-pcl) on native control
            if (e.NewElement != null)
                UpdateTextOnControl();
        }

        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            //if there is change in text or font-style, trigger update to redraw control
            if(e.PropertyName == nameof(Label.Text) 
               || e.PropertyName == nameof(Label.FontFamily) 
               || e.PropertyName == nameof(Label.FontSize)
               || e.PropertyName == nameof(Label.TextColor)
               || e.PropertyName == nameof(Label.FontAttributes))
            {
                UpdateTextOnControl();
            }
        }

        void UpdateTextOnControl()
        {
            if (Control == null)
                return;

            //define paragraph-style
            var style = new NSMutableParagraphStyle()
            {
                Alignment = UITextAlignment.Justified,
                FirstLineHeadIndent = 0.001f,
            };

            //define attributes that use both paragraph-style, and font-style 
            var uiAttr = new UIStringAttributes()
            {
                ParagraphStyle = style,
                BaselineOffset = 0,

                Font = Control.Font
            };

            //define frame to ensure justify alignment is applied
            Control.Frame = new RectangleF(0, 0, (float)Element.Width, (float)Element.Height);

            //set new text with ui-style-attributes to native control (UILabel)
            var stringToJustify = Control.Text ?? string.Empty;
            var attributedString = new Foundation.NSAttributedString(stringToJustify, uiAttr.Dictionary);
            Control.AttributedText = attributedString;
            Control.Lines = 0;
        }
    }
}

Sur la plate-forme Android, c'est un peu plus compliqué - car Android ne prend pas en charge l'alignement de TextView -, nous devrons donc utiliser une WebView à la place pour que le texte soit restitué. 

(Remarque: Vous pouvez également utiliser alternativement une bibliothèque Android et l’utiliser à la place de WebView)

[Assembly: ExportRenderer(typeof(JustifiedLabel), typeof(JustifiedLabelRenderer))]
namespace SomeAppNamespace.Droid
{
    //We don't extend from LabelRenderer on purpose as we want to set 
    // our own native control (which is not TextView)
    public class JustifiedLabelRenderer : ViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<View> e)
        {
            base.OnElementChanged(e);

            //if we have a new forms element, we want to update text with font style (as specified in forms-pcl) on native control
            if (e.NewElement != null)
            {
                if (Control == null)
                {
                    //register webview as native control
                    var webView = new Android.Webkit.WebView(Context);
                    webView.VerticalScrollBarEnabled = false;
                    webView.HorizontalScrollBarEnabled = false;

                    webView.LoadData("<html><body>&nbsp;</body></html>", "text/html; charset=utf-8", "utf-8");
                    SetNativeControl(webView);
                }

                //if we have a new forms element, we want to update text with font style (as specified in forms-pcl) on native control
                UpdateTextOnControl();
            }   
        }

        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            //if there is change in text or font-style, trigger update to redraw control
            if (e.PropertyName == nameof(Label.Text)
               || e.PropertyName == nameof(Label.FontFamily)
               || e.PropertyName == nameof(Label.FontSize)
               || e.PropertyName == nameof(Label.TextColor)
               || e.PropertyName == nameof(Label.FontAttributes))
            {
                UpdateTextOnControl();
            }
        }

        void UpdateTextOnControl()
        {
            var webView = Control as Android.Webkit.WebView; 
            var formsLabel = Element as Label;

            // create css style from font-style as specified
            var cssStyle = $"margin: 0px; padding: 0px; text-align: justify; color: {ToHexColor(formsLabel.TextColor)}; background-color: {ToHexColor(formsLabel.BackgroundColor)}; font-family: {formsLabel.FontFamily}; font-size: {formsLabel.FontSize}; font-weight: {formsLabel.FontAttributes}";

            // apply that to text 
            var strData =
                $"<html><body style=\"{cssStyle}\">{formsLabel?.Text}</body></html>";

            // and, refresh webview
            webView.LoadData(strData, "text/html; charset=utf-8", "utf-8");
            webView.Reload();
        }

        // helper method to convert forms-color to css-color
        string ToHexColor(Color color)
        {
            var red = (int)(color.R * 255);
            var green = (int)(color.G * 255);
            var blue = (int)(color.B * 255);
            var alpha = (int)(color.A * 255);
            var hex = $"#{red:X2}{green:X2}{blue:X2}";

            return hex;
        }
    }
}

Utilisation de l'échantillon

<StackLayout Margin="20">
    <Entry x:Name="InputEntry" />

    <Label Margin="0,10,0,0" BackgroundColor="Navy" TextColor="White" Text="Normal Text Label" FontSize="15" HorizontalOptions="CenterAndExpand" />
    <Label 
            FontSize="20" 
            FontAttributes="Bold"  
            Text="{Binding Text, Source={x:Reference InputEntry}}" />

    <Label Margin="0,10,0,0" BackgroundColor="Navy" TextColor="White" Text="Justified Text Label" FontSize="15" HorizontalOptions="CenterAndExpand" />
    <local:JustifiedLabel 
            FontSize="20" 
            FontAttributes="Bold" 
            Text="{Binding Text, Source={x:Reference InputEntry}}"
            TextColor="Green"
            BackgroundColor="Yellow"
            VerticalOptions="FillAndExpand"
            HorizontalOptions="FillAndExpand" />

</StackLayout>

 enter image description here  enter image description here

19
G.Sharada

Je pense que tu peux essayer avec

HorizontalOptions=LayoutOptions.FillAndExpand

HorizontalOptions

3
Alessandro Caliaro

Je n'ai jamais vu de solution simple à cela, seulement des solutions de contournement comme mentionné ici .

Vous devez utiliser un composant ou créer votre propre solution pour chaque plate-forme.

0
Diego Rafael Souza