如何在xamarin表单中的标签文本上画一条线

时间:2017-03-03 10:37:54

标签: c# xamarin xamarin.forms

如下图所示,我需要在标签文本上动态绘制一条线。这是我在listview中的标签

enter image description here

有人可以告诉我这个吗?

6 个答案:

答案 0 :(得分:9)

在这里,您可以自己控制(strikedLabel)并放置此代码。为了使它更有趣和灵活,您可以添加可绑定属性,如(IsStriked,StrikeColor等),请记住标签和BoxView之间的顺序很重要

<Grid>
    <Label VerticalOptions="Center" Text="Sample string" />
    <BoxView HeightRequest="3"
    VerticalOptions="Center"
    Opacity="0.5"
    Color="Aqua" />
</Grid>

答案 1 :(得分:4)

使用非常简单效果请执行以下步骤:

<强>的Xaml

<Label Text="{Binding TotalReatilAmount}" >
    <Label.Effects>
        <Helpers:LineThroughEffect />
    </Label.Effects>
</Label>

请勿忘记在XAML标题中添加以下内容

xmlns:Helpers="clr-namespace:MyNameSpace.Helpers"

创建一个继承自RoutingEffect

的类
public class LineThroughEffect : RoutingEffect
    {    
        public LineThroughEffect() : base("MyNameSpace.Helpers.PlatformLineThroughEffect") { }
    }

为平台特定

创建渲染

<强>的iOS

[assembly: ResolutionGroupName("MyNameSpace.Helpers")]
[assembly: ExportEffect(typeof(PlatformLineThroughEffect), nameof(PlatformLineThroughEffect))]
namespace MyNameSpace.iOS.Renderers
{
    public class PlatformLineThroughEffect : PlatformEffect
    {
        protected override void OnAttached()
        {
            SetUnderline(true);
        }

        protected override void OnDetached()
        {
            SetUnderline(false);
        }

        protected override void OnElementPropertyChanged(System.ComponentModel.PropertyChangedEventArgs args)
        {
            base.OnElementPropertyChanged(args);

            if (args.PropertyName == Label.TextProperty.PropertyName ||
                args.PropertyName == Label.FormattedTextProperty.PropertyName)
            {
                SetUnderline(true);
            }
        }

        private void SetUnderline(bool underlined)
        {
            try
            {
                var label = (UILabel)Control;
                if (label != null)
                {
                    var text = (NSMutableAttributedString)label.AttributedText;
                    if (text != null)
                    {
                        var range = new NSRange(0, text.Length);
                        if (underlined)
                        {
                            text.AddAttribute(UIStringAttributeKey.StrikethroughStyle,
                                NSNumber.FromInt32((int)NSUnderlineStyle.Single), range);
                        }
                        else
                        {
                            text.RemoveAttribute(UIStringAttributeKey.StrikethroughStyle, range);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ex.Track();
            }
        }
    }
}

答案 2 :(得分:3)

由于Xamarin.Forms不提供开箱即用的此功能,因此您需要通过为每个平台创建custom renderer来扩展Label。通过这样做,您可以访问每个平台上的本机控件(Android上的TextView和iOS上的UILabel)并在那里实现删除线效果。

  1. 在Android上,您在TextView上STRIKE_THRU_TEXT_FLAG。您需要在自定义渲染器中使用以下内容:someTextView.PaintFlags = Paint.StrikeThruText;
  2. 在iOS上,您应该遵循Xamarin论坛上this thread的指导。基本上,您使用UIStringAttributes来获得所需的结果。
  3. 如果您不熟悉自定义渲染器,请查看有关如何自定义Entry控件here的入门教程。

    编辑:实际上,您甚至可以使用效果将其拉下来。更多信息here

答案 3 :(得分:2)

我认为,与其像使用不同的布局或框视图来实现它,不如使用Xamarin提供的Label的TextDecorations属性,如下所示。

<Label
      Text="$200"
      TextDecorations="Strikethrough" />

答案 4 :(得分:0)

我要在此答案中添加我的Android端实现。我根据本文改编而成:https://smstuebe.de/2016/08/29/underlinedlabel.xamarin.forms/

using Android.Graphics;
using Android.Widget;
using MyNamespace.Core.CustomRenderers;
using MyNamespace.Droid.Library.ViewRenderers;
using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ResolutionGroupName(StrikethroughEffect.EffectNamespace)]
[assembly: ExportEffect(typeof(StrikethroughEffectAndroid), nameof(StrikethroughEffect))]
namespace MyNamespace.Droid.Library.ViewRenderers
{
    public class StrikethroughEffectAndroid : PlatformEffect
    {
        protected override void OnAttached()
        {
            RenderEffect(true);
        }

        protected override void OnDetached()
        {
            RenderEffect(false);
        }

        protected override void OnElementPropertyChanged(System.ComponentModel.PropertyChangedEventArgs args)
        {
            base.OnElementPropertyChanged(args);

            if (args.PropertyName == Label.TextProperty.PropertyName || args.PropertyName == Label.FormattedTextProperty.PropertyName)
            {
                RenderEffect(true);
            }
        }

        private void RenderEffect(bool shouldApply)
        {
            try
            {
                var textView = (TextView)Control;
                if (shouldApply)
                {
                    textView.PaintFlags |= PaintFlags.StrikeThruText;
                }
                else
                {
                    textView.PaintFlags &= ~PaintFlags.StrikeThruText;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Cannot strike-through Label. Error: ", ex.Message);
            }
        }
    }
}

干杯!

答案 5 :(得分:0)

Text decorations property可以轻松做到这一点。您只需要设置此属性即可。

<Label Text="This is text with strikethrough." TextDecorations="Strikethrough" />

但是,如果要在运行时动态地进行此操作,则必须绑定此属性。

在xamarin上有一个IValueConverter界面可用于此目的。您可以创建如下所示的转换器:

  public class StatusToTextDecoration : IValueConverter
   {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var decorationText = TextDecorations.None;
        if (value == null) return decorationText;

        if (System.Convert.ToInt32(value) == MyStatus) decorationText = TextDecorations.Strikethrough;

        return decorationText;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        //For this case you can ignore this
        return null;
    }
   }

而不仅仅是您必须将此转换器添加到您的xaml页面作为参考:

xmlns:converterLocal="clr-namespace:MyApp.Converter;assembly=MyApp"

,并在引用后设置为页面顶部的资源:

 <ContentPage.Resources>
    <converterLocal:StatusToTextDecoration x:Key="StatusToTextDecoration"/>
</ContentPage.Resources>

在这里,只需将转换器设置在标签上即可:

<Label Text="This is text with strikethrough." TextDecorations="{Binding MyStateId, Converter={StaticResource StatusToTextDecoration}}" />

它会根据数据源中“ MyStateId”字段的值来设置文字修饰。