简体   繁体   English

Xamarin Forms 条目中的删除线文本

[英]Strikethrough text in Entry in Xamarin Forms

Recently I have come across a business need where I have to show strikethrough text in the Entry of Xamarin Forms.最近我遇到了一个业务需求,我必须在 Xamarin 表单的条目中显示删除线文本。 Now there is a Text decoration property for strikethrough in Label, But there is no such property that exists for Entry.现在Label中有删除线的Text装饰属性,但Entry没有这样的属性。 Now we have an entry like this,现在我们有一个这样的条目, 在此处输入图片说明

But we need to show a strikethrough over sddad .但是我们需要在sddad上显示删除线。 There are some resources that say to use effects or Unicode's strikethrough character set.有一些资源说要使用效果或 Unicode 的删除线字符集。 But it does not fulfill our needs.但它不能满足我们的需求。 Does anybody know how to implement this so that we can change the text to have a strikethrough via a property binding?有谁知道如何实现这一点,以便我们可以通过属性绑定将文本更改为带有删除线?

Any help will be greatly appreciated.任何帮助将不胜感激。

Whenever you want custom UI behaviour in Xamarin.Forms that is not exposed through the Forms API, you will need to go down to the platform level.每当您希望 Xamarin.Forms 中的自定义 UI 行为不通过 Forms API 公开时,您将需要深入到平台级别。

The strikethrough text can be achieved using any of: CustomRenderer , Effect , Behaviour .删除线文本可以使用以下任何一个来实现: CustomRendererEffectBehaviour

Below is an example of a platform effect that will strikethrough the whole text:以下是将删除整个文本的平台效果示例:

Define An Effect定义效果

In your cross platform project create a new RoutingEffect :在你的跨平台项目中创建一个新的RoutingEffect

using Xamarin.Forms;

namespace StrikethroughEntry.Effects
{
    public class StrikethroughEntryEffect : RoutingEffect
    {
        public StrikethroughEntryEffect()
            : base("StrikethroughEntry.Effects.StrikethroughEntryEffect")
        {
        }
    }
}

Implement On iOS在 iOS 上实施

Somewhere in your iOS project create a PlatformEffect在你的 iOS 项目的某个地方创建一个PlatformEffect

using Foundation;
using StrikethroughEntry.Effects;
using StrikethroughEntry.iOS;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ResolutionGroupName("StrikethroughEntry.Effects")]
[assembly: ExportEffect(typeof(iOSStrikethroughEntryEffect), nameof(StrikethroughEntryEffect))]

namespace StrikethroughEntry.iOS
{
    public class iOSStrikethroughEntryEffect : PlatformEffect
    {
        private static NSNumber _strikethroughStyle => new NSNumber((int)NSUnderlineStyle.Single);

        private string _originalText;

        protected override void OnAttached()
        {
            var textField = Control as UITextField;

            if (textField is null)
                return;

            _originalText = textField.Text;

            var attributedText = new NSMutableAttributedString(textField.Text);

            attributedText.AddAttribute(UIStringAttributeKey.StrikethroughStyle, _strikethroughStyle, new NSRange(0, textField.Text.Length));

            textField.AttributedText = attributedText;
        }

        protected override void OnDetached()
        {
            var textField = Control as UITextField;

            if (textField is null)
                return;

            textField.AttributedText = null;

            textField.Text = _originalText;
        }
    }
}

This sample shows how you can cleanup the effect once it is no longer needed.此示例展示了如何在不再需要效果后对其进行清理。 The way attributed strings works on iOS would make is very easy to extend your strikethrough behaviour to target parts of the entry.属性字符串在 iOS 上的工作方式很容易将删除线行为扩展到条目的目标部分。 Perhaps you only want to strikethrough specific words etc.也许您只想删除特定的单词等。

Implement On Android在 Android 上实现

Somewhere in your Android project create a PlatformEffect :在你的 Android 项目的某个地方创建一个PlatformEffect

using Android.Graphics;
using Android.Widget;
using StrikethroughEntry.Droid;
using StrikethroughEntry.Effects;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ResolutionGroupName("StrikethroughEntry.Effects")]
[assembly: ExportEffect(typeof(AndroidStrikethroughEntryEffect), nameof(StrikethroughEntryEffect))]

namespace StrikethroughEntry.Droid
{
    public class AndroidStrikethroughEntryEffect : PlatformEffect
    {
        private PaintFlags _originalFlags;

        protected override void OnAttached()
        {
            var editText = Control as EditText;

            if (editText is null)
                return;

            _originalFlags = editText.PaintFlags;

            editText.PaintFlags = PaintFlags.StrikeThruText;
        }

        protected override void OnDetached()
        {
            var editText = Control as EditText;

            if (editText is null)
                return;

            editText.PaintFlags = _originalFlags;
        }
    }
}

This implementation would require updating if you wanted to strikethrough specific areas of your Entry .如果您想删除Entry特定区域,则此实现将需要更新。

Consume The Effect消费效果

This example will be through xaml:此示例将通过 xaml:

  • Import the effects namespace: xmlns:effects="clr-namespace:StrikethroughEntry.Effects"导入效果命名空间: xmlns:effects="clr-namespace:StrikethroughEntry.Effects"
  • Add effect to target Entry :为目标Entry添加效果:
<Entry Text="This entry has strikethrough">
    <Entry.Effects>
        <effects:StrikethroughEntryEffect />
    </Entry.Effects>
</Entry>

Results结果

Now you have a lovely Entry with strikethrough text!现在您有一个带有删除线文本的可爱Entry

Android安卓 iOS IOS
带有删除线的 Android 条目 带删除线的 iOS 入口

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM