【问题标题】:Strikethrough text in Entry in Xamarin FormsXamarin 表单中的条目中的删除线文本
【发布时间】:2021-12-09 04:41:20
【问题描述】:

最近我遇到了一个业务需求,我必须在 Xamarin 表单的条目中显示删除线文本。现在Label中有删除线的Text修饰属性,但是Entry没有这样的属性。 现在我们有一个这样的条目,

但我们需要在 sddad 上显示删除线。有一些资源说使用效果或 Unicode 的删除线字符集。但它并不能满足我们的需求。 有谁知道如何实现这一点,以便我们可以通过属性绑定将文本更改为删除线?

任何帮助将不胜感激。

【问题讨论】:

  • 不幸的是,android 不支持在其文本输入中添加删除线。所以 Xamarin Forms 不会尝试支持这一点。如果你 google android strike through text entry,你可以找到 android (java) 代码,来制作你自己的“自定义控件”。您可以制作一个 Xamarin Custom Renderer,并将该 java 代码手动翻译为 C#。另一种方法是“作弊”:制作一个单格网格。在该网格中,在您的条目顶部放置一个“带有删除线的标签”。所以它“看起来”在条目内。然后是一个问题,即如何在用户类型中使这种动态变化。查看EffectsTriggers
  • 我不确定条目的属性绑定是什么。是否要为更新输入一一打上删除线?或者您只是想在输入转换器等所有字符以更改值时更改它?
  • @WendyZang-MSFT 我们希望根据标志显示删除线,例如复选框中的 Ischecked 属性。我们希望该属性是可绑定的。

标签: c# xaml xamarin.forms xamarin.android xamarin.forms.entry


【解决方案1】:

只要您希望在 Xamarin.Forms 中自定义 UI 行为而不通过 Forms API 公开,您就需要进入平台级别。

删除线文本可以使用以下任何一种来实现:CustomRendererEffectBehaviour

下面是一个平台效果的示例,它将删除整个文本:

定义效果

在您的跨平台项目中创建一个新的RoutingEffect

using Xamarin.Forms;

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

在 iOS 上实现

在你的 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;
        }
    }
}

此示例展示了如何在不再需要效果时对其进行清理。属性字符串在 iOS 上的工作方式很容易将您的删除线行为扩展到条目的目标部分。也许您只想删除特定单词等。

在 Android 上实现

在你的 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;
        }
    }
}

如果您想删除 Entry 的特定区域,则需要更新此实现。

消耗效果

这个例子将通过 xaml:

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

结果

现在你有一个可爱的Entry,带有删除线!

Android iOS

【讨论】:

  • 因为这是一个很好的解决方案,但是你能告诉我一些关于如何使删除线成为可绑定属性的想法吗?
  • 如果您想将其创建为可绑定属性,您可以将其添加到效果中。我建议看看Xamarin Community Toolkit 如何在效果上实现可绑定属性。你可以为真/假做一个布尔值,一个你想要删除的单词的字符串。祝你好运!
  • 感谢您的指导。
  • 另外,您可以使用我向您展示的效果中的代码创建自定义渲染器,并在表单端向控件添加一个新属性。在这种情况下,这可能会更简单一些!
猜你喜欢
  • 1970-01-01
  • 2017-04-23
  • 2019-03-09
  • 1970-01-01
  • 2018-12-02
  • 1970-01-01
  • 2018-06-13
  • 1970-01-01
  • 2019-04-05
相关资源
最近更新 更多